从nib添加自定义视图到viewcontroller

时间:2017-08-08 11:39:56

标签: swift xcode macos cocoa nsviewcontroller

我有一个顶部有自定义视图区域的viewcontroller,如下图enter image description here

所示

我想将自定义xib加载到此区域,我正在努力这样做。 我创建了一个ABC.swift文件,它是NSView的子类和一个同名的.xib文件。 在身份检查器的.xib文件中,我设置了ABC类。 然后在我的viewcontroller viewDidLoad()中尝试执行以下操作

let abcView = Bundle.main.loadNibNamed("ABC", owner: self, topLevelObjects: nil) as ABC

我还在我的vc中为自定义视图创建了一个插座 然后在viewDidLoad()

customView.addSubview(abcView)

但这不起作用,因为abcView属于Bool类型。 谁能告诉我我做错了什么?实现目标的最佳方式是什么?

3 个答案:

答案 0 :(得分:3)

我在NSView上使用以下扩展程序:(与用户Accepted Answer给出的答案相同)

import Foundation
import Cocoa

extension NSView {

    static func loadFromNib(nibName: String, owner: Any?) -> NSView? {

        var arrayWithObjects: NSArray?

        let nibLoaded = Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName), owner: owner, topLevelObjects: &arrayWithObjects)

        if nibLoaded {
            guard let unwrappedObjectArray = arrayWithObjects else { return nil }
            for object in unwrappedObjectArray {
                if object is NSView {
                    return object as? NSView
                }
            }
            return nil
        } else {
            return nil
        }
    }
}

这是在loadView()的{​​{1}}中使用它的方式:

NSViewController

适用于Swift 4,XCode 9.2

答案 1 :(得分:0)

在撰写本文时,macOS只有传统的捆绑加载方式:func loadNibNamed(_ nibName: NSNib.Name, owner: Any?, topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray?>?) -> Bool

它应该将您提供的数组中的nib的顶级对象作为最后一个参数传递:

var objs = NSArray()
Bundle.main.loadNibNamed("MyScreen", owner: self, topLevelObjects: &objs)

请务必检查它是否返回true。否则意味着它无法加载所需的笔尖。

加载后,界面生成器左侧菜单中的对象可在您的代码中使用。如果您的笔尖中有视图,则可以将其添加为子视图:

for obj in objs {
  if obj is MyViewClass {
    // Now we are sure that the obj is really a view of the desired class
    self.someView.addSubview(obj)
  }
}

答案 2 :(得分:0)

已经给出了更紧凑的答案

extension NSView {

    static func loadFromNib(nibName: String, owner: Any? = nil) -> NSView? {
        var arrayWithObjects: NSArray?
        let nibLoaded = Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName),
                                                 owner: owner,
                                                 topLevelObjects: &arrayWithObjects)

        if nibLoaded {
            return arrayWithObjects?.first(where: { $0 is NSView }) as? NSView
        }

        return nil
    }
}