teunteun2
[Swift] XIB를 이용한 커스텀 뷰 만들 때 - required init?(coder:NSCoder) & awakeFromNib() 의 호출 시점 본문
[Swift] XIB를 이용한 커스텀 뷰 만들 때 - required init?(coder:NSCoder) & awakeFromNib() 의 호출 시점
teunteun2 2022. 5. 7. 15:13저번에 UIView의 두 생성자 required init?(coder: NSCoder) & init(frame: CGRect)에 대해 정리하고, 차이점을 알아보는 포스팅 글을 썼는데 이번엔 조금 비슷하게 XIB와 같은 인터페이스 빌더를 통해 커스텀 뷰를 만들 때 사용되는 required init?(coder: NSCoder) 생성자와 awakeFromNib() 메서드 둘에 대해 정리해보고자 합니다 - !
항상 코드로만 커스텀 뷰를 만들다가 XIB와 좀 친해지고자 ...
XIB로 커스텀 네비게이션바를 만들고 (UIView로) 필요한 부분에 넣어쓰고자 했는데요,
init?(coder: NSCoder) 내부에 outlet을 통해 버튼에 addTarget 을 해주고 실행하니 에러가 납니다
뭐라고 뜨느냐 ! 바로 버튼이 nil이라고요 ...
required init?(coder: NSCoder)의 호출 시점
우리가 인터페이스빌더를 통해 커스텀 뷰를 만들어줄 때 해당 생성자가 필요한 이유는 바로
XIB를 nib으로 컴파일 하기 위한 unarchiving/deserialize 과정 때문이라고 했는데요,
따라서 이 생성자가 호출되는 시점은 파일이 unarchiving될 시기이기 때문에 outlet 객체들이 제대로 생성되지 않았을 때입니다.
IBOutlet을 통해 무언가를 해주려고 하기엔 너무 이른 시점인것이죠 (그래서 버튼이 nil로 뜬 것!)
해당 생성자에서는 outelt 혹은 frame과 관련된 UI 객체에 접근해서 무언가를 해주는 작업이 아니라,
UI와 아무 상관 없는 값 변수에 관한 초기화 혹은 값 변경을 주는게 맞을 것 같아요
그럼 대체 outlet 변수들의 속성을 어디서 언제 지정해주어야 하느냐 !
awakeFromNib() 의 호출 시점
애플 문서를 읽어보면 awakeFromNib의 정의는
인터페이스빌더 아카이브 또는 nib 파일로부터 로딩된 후 receiver를 준비하는 메서드라고 하는데요, 더 읽어보면
'init 메서드를 사용하여 초기화하여 모든 객체가 인스턴스화 된 후, 모든 객체에 대한 outlet과 action 연결을 다시 설정합니다. 그런 다음 awakeFromNib 메서드를 호출합니다' 라고 나와있습니다.
생성자를 통해 파일을 언아카이빙하고 생성한 후에, 모든 객체에 대한 연결을 다시 설정하고 호출되는 것이 awakeFromNib.
frame 혹은 IBOutlet과 관련된 속성을 지정해줄 땐 awakeFromNib 호출 시점에 맞추어 코드를 짜주면 될 것 같네요 !