2017-12-27 6 views
0

xibファイルからビューをロードしようとしています。私がやりたいことは、私にとってはかなりシンプルなように思えますが、なんらかの理由で、私は思ったよりずっと難しいです。同じウィンドウ(スタックビュー)で何度も再利用したいカスタムビュー(ラベル、ボタン、テーブルビュー)があります。ここに私のカスタムビューのコードがあります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. 
    } 
} 

ここに私のビューは、メインView Controllerの読み込みでした。スタックビューで同じビューを2つ表示する必要があるため、2回実行しています。問題は、エラーが発生していることです。この行はであり、多くの問題を引き起こしています。これは、アプリを実行するときにのみ発生します。それはかなり無作為で、私はなぜそれが起こっているのかわかりません。これを行うより良い方法はありますか?または私のコードで何か間違っているのですか?

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ファイル(サブビュー付き)には1つのビューしかありませんでしたが、インターフェースビルダーは無視する必要があるものも追加しました。私のテストでは、トップレベルのオブジェクトはTestViewとNSApplicationのインスタンスでした。私は2番目の項目だったTestViewを取得するために配列をチェックしなければならなかった。 –

答えて

0

インスタンス化は、(あなたがそれについては本当に興味がある場合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を最終的な配列にラップしていないので、私の例を更新しました。 –

関連する問題