[iOS] Xib 를 이용해 CustomView 사용해보기

nnnyeong·2022년 10월 24일
0

iOS

목록 보기
17/17
post-custom-banner

iOS 에서 CustomView 를 이용하고자 할 때

  • 코드를 사용해 programmatically 하게 작성하기
  • xib 이용하기

두가지 방법이 존재한다. 이 중 xib 를 활용한 방법에 대해 공부해보았다.
sujinnaljin 님의 블로그 를 보며 많이 배우는데 신기하게도 옛날 옛적 함께 프로젝트를 했던 친구? 동생? 이었다!!! 보면서 참 반성도 하고 배우기도 한다. 저 블로그와 함께라면 든든해..




1. Xib 이용하기

지난 포스팅에서 Nib, Xib는 유저 인터페이스 필드를 저장하기위한 파일이고 UITableViewController, UITalbeViewCell, UICollectionCell클래스, CustomView에서만 지원 가능하다는 사실을 다시 떠올리면서!

MyCustomView.swift 와 MyCustomView.xib 를 만들고 이를 연결할 때

  • File's Owner 를 세팅
  • Custom Class 를 세팅

하는 두 가지 방법이 존재한다.



1) File's Owner 를 세팅하기

MyCustomView.xib 의 File's Owner 로 xib 를 세팅한 뒤 MyCustomView.swift 에서 해당 뷰를 가져오기 위해서는 nib 형태로 불러와야 하고, 이 때 또 두가지 방법이 존재한다!

(이진트리냐고.. 계속 가지치기 해서 헷갈려 혼났네)

  • loadNibNamed 함수 사용
  • UINib 생성 후 instantiate 함수 사용


1️⃣ loadNibNamed 사용

먼저 loadNibNamed 메소드를 살펴보면

  • 1) name : xib 파일의 이름을 의미한다 ("MyCustomView")
    • 이는 이후 Outlet 이나 IBAction 을 해당하는 Owner 에 잘 연결할 수 있도록 해 주는 역할을 함!
  • 2) owner : 해당 xib 파일의 owner 의 인스턴스를 의미한다!

아까 xib 파일에서 File's Owner 를 지정해 주었지만 이는 xib를 소유할 클래스의 타입을 지정해준 것을 의미한다. 즉 실제적으로 해당 xib 를 소유할 인스턴스를 owner 매개변수를 통해 설정해 주어야 한다!

  • 3) loadNibNamed 메소드의 반환형을 보면 [Any]? 타입인데, loadNibNamed 를 통해 로드된 뷰가 여러개의 뷰들과 하위 뷰들을 가질 수 있기 때문에 이와 같은 반환형을 가지고, 때문에 이를 사용할 때 .first 와 같이 접근해 사용할 수 있다!

이후 ViewController 에서 Custom Class에 MyCustomView.swift 를 설정해주면 적용 완료이다!

이 때, ViewController 가 로드되는 시점에 커스텀 뷰 클래스의 init() 이 생성된다. Main 스토리보드에서 Custom Class 를 MyCustomView 로 설정했기 때문에 시스템이 Nib 파일을 unarchive 하려 하고 이 때, MyCustomView 의 init?(coder: NSCoder) 이 호출되어 xib 파일을 로드하는 customInit() 메소드가 호출된다!



2️⃣ UINib 생성 후 instantiate

1️⃣ loadNibNamed 사용 와 거의 유사한 방법이다. Nib 를 불러올 때 Bundle 에서 loadNibNamed 를 사용해 불러오지 않고 UINib 를 사용해 instantiate 하여 반환되는 [Any] 뷰 배열은 .first 로 동일하게 접근해서 사용한다.

  • UINib class는 nib 파일의 컨텐츠를 래핑하는 객체이고 nib 파일의 뷰들을 메모리에 캐시하고 있다가, instantiate 할 때 언아카이빙한다.



2) Custom Class 세팅하기

두번째 방법은 xib 파일의 Custom Class 를 설정하는 것이다.

하지만 위처럼 Custom Class 만 설정하고 다른 코드 변경 없이 실행하면 무한루프가 발생한다! 잉?

그 이유는, 앱이 실행되고 ViewController가 로드 되자마자 시스템은 MyCustomView 의 init(coder: NSCoder) 를 호출하고 자연스레 customInit() 이 호출되면

-> customInit()에서 xib 를 로드되고

-> xib 파일에는 Custom Class 가 지정되어 있다..!
-> .. 잉?
... 분명 이해했는데..이상하다~ 다시 다시..!



1) xib의 CustomView Class가 MyCustomView로 설정된 뷰를 스토리보드 (여기선 Main) 에 추가
2) ViewController 가 로드될 때 CustomView Class 의 init(coder: NSCoder) 이 호출됨
3) init(coder: NSCoder) 에서는 MycustomView 의 customInit 이 호출됨
4) customInit 에서 loadNibNamed 를 호출해 xib 를 로드
5) xib의 최상위 view는 Custom Class 로 MycustomView 가 설정되어 있음
6) 따라서 MycustomView 의 init(coder: NSCoder) 이 다시 호출됨
7) 무한 루프 발생!

이러고도 까먹을 것 같아 그림을 그려봄 !

때문에 이러한 무한루프 발생을 방지하기 위해 xib의 Custom Class를 이용할 때에는

  • init(coder: NSCoder) 이나 init(frame: CGRect) 와 같은 init 메소드에서 xib 를 로드하지 말아야 한다!
    • 4) -> 5) 를 끊어주는 것
  • Custom Class 대신 부모 클래스나 다른 클래스에서 xib 를 로드하도록 한다!

💡 여기서는 loadNibNamed 의 owner를 nil로 설정함! -> 추후 보완 내용

이처럼 Custom Class 설정 시 CustomView Class 는 Outlet 과IBAction 만 가질 수 있다!




File's Owner 사용 장점

보아하니 아무래도 난 File's Owner를 쓰게 될 것 같다

  • 코드, 스토리보드, xib 를 사용하여 앱 전체에서 Custom Class를 재사용할 수 있다.
    • 다른 방법들은 무한루프가 발생함
  • 부모클래스나 다른 클래스에서, 즉 Custom Class 바깥에서 xib 를 로드하는 번거로움이 없다!
    • xib 로드를 Custom Class 안에서 완료함
  • File's Owner 는 상위 클래스 또는 일부 다른 클래스를 대신하는 클래스일 뿐이므로 좀 더 clean 한 접근 방식

그 자체로 포장되어 있는 reusable class를 제공해 다수의 File's Owner 및 outlet을 갖는데서 오는 혼란을 방지할 수 있음!!

어떤.. 완제품 같은 느낌이다 이리 보니, 사용자가 굳이 개입할 필요없이 갔다 쓰면되는 프레임워크 같은 느낌?




아카이빙과 언아카이빙

아카이빙

객체의 프로퍼티들을 모두 기록하고 파일 시스템에 그 내용을 저장하는 것을 포함한다. iOS 에서 모델 객체를 저장하는 가장 흔한 방법 중 하나이다.

언아카이빙

아카이브한 데이터들로부터 객체를 다시 만든다.

아카이브하고 언아카이브 해야하는 클래스들은 NSCoding 프로토콜을 conform 하고 두 필수 메소드인

  • func encode(with aCoder: NSCoder)
  • required init?(coder aDecoder: NSCoder)
    의 구현이 요구된다!

(UIView sms NSCoding을 따른다.)

  • 1 : NSCoder로 나타나는 encoder (archiver object)를 이용해서 모든 프로퍼티를 인코딩 한다.
  • 2 : NSCoder로 나타나는 decoder (unarchiver object) 안의 data 를 이용해서 초기화한 객체를 반환한다.

아카이빙은 xib 파일을 만드는 방법이기도 하다. xib 파일이 저장되면 view들을 해당 xib 파일에 아카이브하고, 필요한 시점에 뷰들을 xib 파일에서 언아카이브한다. xib 파일과 표준 아카이브 사이에 약간의 차이는 있지만 전반적인 과정은 비슷하다.


  • archive = 객체를 하위 뷰들을 압축하고 그 내용을 기록!
  • unarchive = xib에 이렇게 저렇게 변형되어 저장된 뷰들을 압축 해제!

정도로 이해하면 될 것 같다..!




Reference

[Swift] 커스텀 뷰 xib 연결하기 : File’s Owner vs Custom Class
XIB를 사용한 UIView Custom 제대로 이해하기

profile
주니어 개발자까지 ☄️☄️
post-custom-banner

0개의 댓글