관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] init(frame:), required init?(coder aDecoder: NSCoder), prepareForInterfaceBuilder(), awakeFromNib() 초기화의 정체 본문

iOS 기본 (swift)

[iOS - swift] init(frame:), required init?(coder aDecoder: NSCoder), prepareForInterfaceBuilder(), awakeFromNib() 초기화의 정체

jake-kim 2020. 11. 16. 23:01

init(frame: CGRect)

  • Interface Builder에서 쓰이지 않고, 코딩으로 UIView를 상속받은 클래스를 만들 때 사용
  • ex) let sampleButton = UIButton(frame: CGRect(x:3, y:4, width:5, height:6))

required init?(coder aDecoder: NSCoder)

  • Interface Builder에서 생성되는 초기화 구문

View나 Button과 같은 것을 커스텀하는 경우, 위 두 가지의 초기화 구문이 필수

class MyCustomView: UIView {

    @IBOutlet weak var mainTitle: UILabel!
    @IBOutlet weak var subTitle: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }

    func setupView() {
		let view = UIView()
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
    }
}

awakeFromNib()

  • Interface Builder에서 객체가 init(coder:)로 초기화(인스턴스화)된 후 호출
  • IB에서 inspector와 같은 방법으로 값을 조정하면 위 커스텀 클래스는 아카이브되어 있다가 언아카이브로 변화 되는데,
    (이 때 init(coder:)가 호출되며 내부 속성이 초기화 -> init시점에는 frame과 관련된 크기, 위치 등이 정해지지 않은 상태)
  • 위 단계에서 IB는 연결된 객체의 변수를 사용하려고 할 때 awakeFromNib()을 사용

* XIB: XML Interface Builder, "flat file" (아무런 구조적 상호관계가 없는 레코드들이 모여있는 파일)

* NIB: NeXT Interface Builder (빌드시, XIB가 NIB로 변환)

 

  • 처음부터 NIB로 저장하면 될 것을, XIB로 저장하는 이유?
    XIB가 SCM(source control management : 소스 제어 관리)시스템에 유리하기 때문

prepareForInterfaceBuilder()

  • @IBDesignable지정하여 커스텀 뷰를 만든 경우에 선언하여 사용
  • 아래의 설명과 같이, 인터페이스 빌더에서 디자인 타임에 초기화 되는 함수

  • 예제)
class MyCustomView: UIView {

    @IBOutlet weak var mainTitle: UILabel!
    @IBOutlet weak var subTitle: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupView()
    }
    
    ovveride func prepareForInterfaceBuilder() {
    	super.prepareForInterfaceBuilder()
        setupView()
    }

    func setupView() {
		let view = UIView()
        view.frame = bounds
        view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        addSubview(view)
    }
}

 

Comments