2015년 3월 3일 화요일

[iOS] XIB를 이용한 UIView 서브클래싱 (+영상)

UIView 기반의 클래스를 만들 때 XIB를 이용해 뷰 디자인을 하는 방법에 대해 정리한다. 기초적인 내용이긴 하지만 그래서 워낙 자주 까먹는 내용이다. -_-;

동일한 내용의 영상. 글보다 영상이 좋다면 보자. 직접 제작한 영상이라 영어는 전부 콩글리쉬이다. -_-;;

1. UIView 서브클래스 추가 및 XIB 파일 추가

기존의 Xcode 프로젝트에서 파일 추가하듯이 Cocoa Touch Class를 추가한다. 물론 부모클래스는 UIView로 해야한다. 여기서는 CustomView 라는 클래스 이름을 정의했다고 가정하자.

그리고 XIB파일을 추가한다. 새 파일 추가 시 User Interface 카테고리의 View 항목을 선택하면 된다. 이름은 원하는 대로 지어도 되지만 통일성(?)을 위해 동일한 CustomView.xib 라는 이름을 지어줬다고 가정하자.


2. XIB 편집

추가한 XIB 파일(CustomView.xib)을 열면 인터페이스 빌더 화면이 나타난다. 여기서 File's owner 클래스를 아까 추가한 UIView 서브클래스(CustomView)로 지정해 주어야 한다.


그 이외에는 편집하고 싶은대로 하면 된다. 기존에 하던대로 뷰 컴포넌트를 추가하고 소스코드와 연결하는Outlet도 동일한 방식으로 만들면 된다. File's owner 를 세팅해 뒀기 때문에 어시스턴트 에디터를 열면 CustomView 클래스가 자동으로 표시될 것이다. (자동으로 표시되지 않으면 automatic으로 변경하자)

3. XIB 로드

위 까지만 해서는 XIB의 뷰가 정상적으로 로딩되지 않는다. 이제 추가한 UIView 서브클래스(CustomView.swfit 파일​)를 코딩할 차례가 남아있다.

아래와 같은 방식으로 3개의 메소드를 작성한다.
class CustomView: UIView {

    ...   

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.commonInitialization()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.commonInitialization()
    }
    
    func commonInitialization() {
        let view = NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, options: nil).first as UIView
        view.frame = self.bounds
        self.addSubview(view)
    }

    ...
}
여기서 init, 즉 생성자가 두 개가 쓰이고 있다.
  • 가장 첫 번째 init은 UIView의 기본이 되는 initWithFrame 생성자이다. 이 생성자는 코드로 이 뷰를 생성하게 되면 부르게 되므로 만약 코드로 뷰를 생성한다면 필요하다.
  • 그 다음 initWithCoder에 해당하는 생성자는 XIB에 의해 이 뷰가 추가되었을 때 불리는 생성자이다. 물론 이 생성자의 코드 내용을 awakeFromNib() 메소드 안으로 넣어도 동작하긴 하지만 여기다 넣는게 가장 맞다고 생각된다. 
생성자는 둘 중 하나만 있어도 되니 상황에 맞게 구현하자.

마지막 commonInitialization() 메소드에서 NSBundle을 이용해 실제 XIB의 뷰를 로딩한다. "CustomView" 라는건 XIB의 파일 이름에서 확장자 .xib를 뺀 것이라고 추측이 가능할 것이다.

loadNibnNamed 메소드 결과는 [AnyObject] 라는 배열을 돌려준다. 위 코드에서는 first 프로퍼티를 이용해 이 배열의 첫 번째 오브젝트를 가져와 UIView로 타입을 변경한다. 여기서 first 를 사용하는 건 결과물 Array(최상위 오브젝트들) 중에서 첫 번째를 가져온다는 의미이다. 만약 최상위 뷰를 여러개 만들어 넣었다면 여기서 원하는 뷰를 찾아야 겠지만 그럴 가능성은 별로 없다고 생각된다.

이렇게 해서 로드된 XIB의 뷰 크기를 자신의 뷰 크기와 동일하게 맞춰주고 서브뷰로 추가하면 된다.

PS. 이 외에 self를 XIB에서 로드한 결과물로 바꿔치기 하는 방법이 있긴 하지만 개인적으론 그다지 선호하진 않는다. ;;;

4. 마무리

이런 식으로 만들면 이제 뷰 자체의 구현은 끝났다.

나머지는 이 뷰를 코드로 생성하든 인터페이스 빌더나 스토리보드에서 생성하든 마음대로 하면 된다. :-)

[관련글] [OSX] XIB를 이용한 NSView 서브클래싱(+영상)

댓글 2개 :

익명 :

많은 참고가 되었습니다 감사합니다

익명 :

가끔 놓치는 부분인데 정리 감사합니다.