2017-12-27 1033 views
0

我想从xib文件加载视图。我期望做的事情对我来说似乎很简单,但由于某种原因,这比我想象的要困难得多。我只是有一个自定义视图(带有标签,按钮和表格),我想在同一个窗口中多次重复使用(在堆栈视图中)。这里是我的代码为自定义视图加载视图从XIB和获取零的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. 
    } 
} 

这是我的视图在视图主视图控制器负载。我做了两次,因为我需要在堆栈视图中使用两个相同的视图。问题是我得到一个错误。这条线路没有let topLevelObjects = objectArray2?.firstObject as? PlatformView,并导致很多问题。这只有在我运行应用程序时才会发生。这是非常随机的,我不知道它为什么会发生。有一个更好的方法吗?或者我在我的代码中做错了什么?

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

的实例化返回顶层对象的XIB文件,其中一些界面生成器本身可能已添加的阵列(见XIB的布局,如果你真的很好奇吧)。

简单的方式是搜索返回的topLevelObjects您PlatformView这样的:

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是在厦门国际银行一个更好的解决方案是这样的:

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 
    } 
} 

正如我所说,你必须小心,因为强制解包的可选项。

+0

在平面图之前引用了什么'topLevelObjects?如果你打算把'objectArray'也不起作用。第一种方法似乎最初工作时,我试图它,但如果有一个更优雅的解决方案,我宁愿使用它。 –

+0

对不起。我已经更新了我的示例,因为我已将可选的objectArray解包为一个使用的权威数组。 –

相关问题