2015년 3월 3일 화요일

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

얼핏 생각해서는 UIView 서브클래싱 하는 것과 비슷하리라 생각했는데 API의 사용법이나 결과가 조금씩 달랐다. 그래서 XIB를 이용해 인터페이스 디자인을 할 수 있는 NSView 서브클래싱을 정리해 본다.

이 내용도 영상으로 정리해 놓았다. 영상을 보는 것이 편하다면 아래 영상을 보는 것을 추천한다.


1. 준비사항

두 개의 파일을 추가했다고 하자:
  • CustomView.swift (NSView 서브클래스)
  • CustomView.xib

2. XIB에서 연결

기본적으로 XIB파일의 File's Owner 를 해당 클래스로 세팅해야 하는건 UIView때와 동일하다.

그리고 최상위 뷰의 아웃렛을 해당 클래스에 만들어 주어야 한다.


위 그림의 경우 'Custom View' 라는 이름이 붙은 최상위 뷰를 File's owner의 view 라는 아웃렛 프로퍼티로 연결해 둔 상태이다.

3. XIB 로드

XIB를 로딩하는 코드는 iOS의 방법과 비슷하다.
NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, topLevelObjects: nil)
이렇게 하면 XIB의 내용이 로딩이 되는데, 특이하게도 아웃렛으로 연결해 준 view 라는 프로퍼티에 뷰 인스턴스가 로딩된다. 그렇다면 이 뷰 인스턴스를 그냥 서브뷰로 붙이면 될 것이다.

이 로딩 코드를 생성자에 넣어서 구현한 예제가 아래 코드이다.
class CustomView: NSView {
    @IBOutlet var view: NSView!   // XIB 최상위 뷰
    
    override init(frame frameRect: NSRect) {
        // 뷰를 코드로 생성 할 때 사용되는 생성자
        super.init(frame: frameRect)
        
        NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, topLevelObjects: nil)
        self.view.frame = self.bounds
        self.addSubview(self.view)
    }
    
    required init?(coder: NSCoder) {
        // 뷰가 XIB에 의해 생성될 때 사용되는 생성자
        super.init(coder: coder)
        
        NSBundle.mainBundle().loadNibNamed("CustomView", owner: self, topLevelObjects: nil)
        self.view.frame = self.bounds
        self.addSubview(self.view)
    }
}
두 개의 생성자 내용은 동일하다. 차라리 하나의 공통 메소드로 뽑아내는게 더 좋을 것이다. :-)

마무리

이제 구현은 끝났다. 나머지는 코드로 생성해서 붙이든 인터페이스빌더나 스토리빌더에서 붙이는 마음대로 구워 삶는 일만 남았다.

사실 이 방법 외에 다른 방법이 있을거라 생각되는데, 만약 UIView 와 비슷한 방식으로 구현이 가능하다거나 한다면 참 우울 할 것 같다 -_-;

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

댓글 없음 :