2017-12-27 18 views
0

xib 파일에서보기를로드하려고합니다. 내가 뭘하기를 바라는 것은 나에게 꽤 단순 해 보이지만, 어떤 이유로 그것이 그것이 될 것이라고 생각했던 것보다 훨씬 어렵다. 스택 뷰에서 동일한 창에서 여러 번 재사용하려는 사용자 정의보기 (레이블, 단추 및 tableviews 포함)가 있습니다. 다음은 사용자 정의보기에 대한 내 코드입니다.보기로드 중 XIB 및 nil macOS 응용 프로그램을 받고

class PlatformView: NSView { 
    @IBOutlet var testLabel: NSTextField! 

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

    override func awakeFromNib() { 
     super.awakeFromNib() 
     self.testLabel.stringValue = "Init" 
    } 

    override func draw(_ dirtyRect: NSRect) { 
     super.draw(dirtyRect) 

     // Drawing code here. 
    } 
} 

여기 내보기는 주보기 컨트롤러의로드가 수행 한 것입니다. 스택보기에서 두 개의 동일한보기가 필요하기 때문에 두 번하고 있습니다. 문제는 내가 오류가 발생했습니다. 이 줄은이며 많은 문제를 일으 킵니다. 이는 앱을 실행할 때만 때로 발생합니다. 그것은 꽤 무작위이고 나는 그것이 왜 일어나고 있는지 모른다. 이 작업을 수행하는 더 좋은 방법이 있습니까? 아니면 내 코드에서 뭔가 잘못하고 있는거야?

var objectArray:NSArray? 
guard let nib = NSNib(nibNamed: NSNib.Name(rawValue: "PlatformView"), bundle: nil) else {return} 
if nib.instantiate(withOwner: self, topLevelObjects: &objectArray), let topLevelObjects = objectArray?.firstObject as? PlatformView { 
    self.platformStackView.addArrangedSubview(topLevelObjects) 
    self.firstPlatformView = topLevelObjects 
} 

if nib.instantiate(withOwner: self, topLevelObjects: &objectArray), let topLevelObjects = objectArray?.firstObject as? PlatformView { 
    self.platformStackView.addArrangedSubview(topLevelObjects) 
    self.secondPlatformView = topLevelObjects 
} 
+0

FirstObject가 사용자가 찾고있는 PlatformView임을 보장 할 수 없습니다. 최상위 오브젝트가 여러 개있을 수 있으므로 원하는 PlatformView를 모두 확인해야합니다. 내 테스트에서 하위보기가있는 XIB 파일에서 하나의보기 만 있었지만 인터페이스 작성자는 무시해야하는 항목을 추가했습니다. 내 테스트에서 최상위 수준의 객체는 TestView와 NSApplication 인스턴스였습니다. 두 번째 항목 인 TestView를 얻기 위해 배열을 검사해야했습니다. –

답변

0

이 instantiate 인터페이스 빌더 자체가 추가 한 일부의 XIB 파일의 최상위 객체의 배열을 (당신이 그것에 대해 정말 궁금 경우 XIB의 레이아웃을 참조) 반환합니다.

if nib.instantiate(withOwner: self, topLevelObjects: &objectArray) { 
    if let topLevelObjects = objectArray { 
     let platformView = topLevelObjects.flatMap({ object in return object as? PlatformView }).first! 
     self.platformStackView.addArrangedSubview(platformView) 
     self.firstPlatformView = platformView 
    } 
} 
: 그러나 좀 더 우아한 해결책이 같은 당신의 PlatformView가 XIB에 확신 가정

if nib.instantiate(withOwner: self, topLevelObjects: &objectArray) { 
    for object in topLevelObjects { 
     if let platformView = object as? PlatformView { 
      self.platformStackView.addArrangedSubview(platformView) 
      self.firstPlatformView = platformView 
     } 
    } 
} 

:

간단한 방법은 다음과 같이 당신의 PlatformView의 반환 topLevelObjects를 검색하는 것입니다

내가 말했듯이 옵션을 풀지 않는 힘 때문에 거기에서 조심해야합니다.

+0

평면 맵 앞에 'topLevelObjects'가 무엇입니까? 만약 당신도'objectArray'를 넣으려고했다면 작동하지 않습니다. 첫 번째 방법은 처음 시도 할 때 작동하는 것처럼 보이지만 더 세련된 솔루션이 있으면 오히려이를 사용합니다. –

+0

죄송합니다. 선택적 objectArray를 사용을위한 최종 배열로 래핑하지 않았으므로 예제를 업데이트했습니다. –