본문 바로가기

iOS

required init VS override init

728x90

커스텀 뷰에 대한 작업을 할 때 필수적인 작업 중 하나는 초기화 과정이다. (초기화 과정은 커스텀 뷰가 아니더라도 필수적인 과정 중 하나다.)

 

초기화 작업 중에서 UIView를 다룰 때 많이 볼 수 있는 초기화 문법이 바로 

  • required init?(coder: NSCoder)
  • override init(frame: CGRect) 

이 두가지이다. 이 둘의 차이를 제대로 알고 있어야 사용하는 방법에 맞는 초기화 구문을 작성할 수 있다. 

 

required init?(coder: NSCoder)

xib 파일은 xml 형태로 인터페이스 빌더 구성 정보를 갖고 있다.

컴파일 시 이 파일은 nib 파일로 변환이 되기 때문에 사용자의 화면에서 출력하기 위해서는 init(coder: NSCoder)를 통해 객체를 생성해야 한다. 

 

import UIKit

class MediaCardView: UIView {

    // MARK: - UI Property
    
    @IBOutlet weak var posterImageView: UIImageView!
    
    // MARK: - Initializer
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        loadNib()
        loadUI()
    }
    
    // MARK: - Custom Method
    
    private func loadNib() {
        let view = UINib(nibName: "MediaCardView", bundle: nil).instantiate(withOwner: self, options: nil).first as! UIView
        view.frame = bounds
        self.addSubview(view)
    }
    
    private func loadUI() {
        posterImageView.backgroundColor = .systemMint
    }
}

UINib은 .nib 파일의 내용을 메모리에 캐시하고 있다가 instantiate 시점에 사용자의 화면에 보여준다.

 

override init(frame: CGRect)

인터페이스 빌더에서 사용되지 않고 UIView를 상속 받은 커스텀 클래스를 코드로 구성할 때 사용하는 생성자이다.

 

 required init?(coder: NSCoder) {
     fatalError("init(coder:) has not been implemented")
 }

코드로 커스텀 클래스를 구성할 때는 required init?(coder: NSCoder) 를 함께 호출해야 한다. (만약, 호출하지 않으면 오류가 난다.)

 

import UIKit

class MainMediaHeaderView: UIView {
    
    private var logoImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleToFill
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    }()
    
    private var posterImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleToFill
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        configureUI()
        setLayout()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func configureUI() {
        logoImageView.backgroundColor = .systemPink
        posterImageView.backgroundColor = .black
    }
    
    private func setLayout() {
        addSubview(posterImageView)
        addSubview(logoImageView)
        
        NSLayoutConstraint.activate([
            posterImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0),
            posterImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0),
            posterImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0),
            posterImageView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0),
            
            logoImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 20),
            logoImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20),
            logoImageView.widthAnchor.constraint(equalToConstant: 50),
            logoImageView.heightAnchor.constraint(equalToConstant: 50)
        ])
    }
}

'iOS' 카테고리의 다른 글

YPImagePicker  (0) 2022.08.13
0812 Q&A 정리  (0) 2022.08.12
Kakao 다음(Daum) 검색 API 구현 (feat. Expandable Cell)  (0) 2022.08.08
Cell안의 UIButton 이벤트 처리 (+WebKit View)  (0) 2022.08.08
TMDB - GET / Pagenation  (0) 2022.08.08