swift 为什么我的IBOutlet在使用LoadNibNamed()时为nil,如何修复它?

rqcrx0a6  于 2023-05-21  发布在  Swift
关注(0)|答案(1)|浏览(144)

我正在编写一个Mac应用程序,我有一个从NSView派生的类,其内容在.xib文件中定义。我已经遵循了许多帖子,问题等的指示,我甚至审查了我的一个iOS应用程序的工作代码,它可以按预期工作。当我在故事板中使用自定义视图并运行应用程序时,插座无法连接。我在控制台中得到以下错误:
[Nib正在加载]无法将(标签)出口从(Linkage.SidebarTextEntry)连接到(NSTextField):缺少setter或示例变量
除了连接插座时出现此错误外,代码运行正常,自定义视图按预期显示在应用程序中。看起来是正确的。
这是使用协议和带有加载函数的扩展加载nib文件的代码:

protocol NibLoadable {
    static var nibName: String { get }
    static func createFromNib( in bundle: Bundle ) -> NSView
}

extension NibLoadable where Self: NSView {
    static var nibName: String {
        return String( describing: Self.self )
    }

    static func createFromNib( in bundle: Bundle = Bundle.main ) -> NSView {
        var topLevelArray: NSArray? = nil
        bundle.loadNibNamed( NSNib.Name( nibName ), owner: self, topLevelObjects: &topLevelArray)
        if topLevelArray == nil { return NSView() }
        let views = Array<Any>(topLevelArray!).filter { $0 is NSView }
        return views.last as! NSView
    }
}

这是我的视图类的基类(因为我需要创建一堆不同的视图,这些视图具有类似的代码,这些代码不应该是多余的)。它什么也不做,但它确实存在,并且可能是错误的来源:

class SidebarPriorityItem: NSView, NibLoadable {    
}

具有插座的类:

@IBDesignable
class SidebarTextEntry: SidebarPriorityItem {
    @IBOutlet weak var label: NSTextField!
    @IBOutlet weak var textEntry: NSTextField!
    @IBOutlet weak var indentConstraint: NSLayoutConstraint!

    override func awakeFromNib() {
        print( String( describing: label ) )
        super.awakeFromNib()
    }

    private func commonInit() {
        let child = SidebarTextEntry.createFromNib()
        translatesAutoresizingMaskIntoConstraints = false
        addSubview( child )
    }
    
    override init( frame frameRect: NSRect ) {
        super.init( frame: frameRect )
        commonInit()
    }
    
    required init?( coder: NSCoder ) {
        super.init( coder: coder )
        commonInit()
    }
    
    convenience init() {
        self.init()
        commonInit()
    }
}

下面是我如何在接口生成器中设置自定义类名。我给了文件所有者我的自定义类名,由于递归问题,我没有给予根视图自定义类名,左边是NSView:

以下是标签的出口设置:

根视图只有一个子视图,因此我可以通过使用该子视图的大小来管理自定义视图的固有大小(没有办法在根视图上设置高度约束)。
我想得到一些帮助来诊断这个问题。
我已经清理了这个项目。我已经删除了项目的所有派生数据。关闭并重新启动Xcode

axr492tv

axr492tv1#

我通过将createFromNib()函数从静态更改为非静态,并调整其他代码使其正常工作(比如使用“Self.nibName”访问nibName)来修复这个问题。这就是NibLoadable类现在的样子:

protocol NibLoadable {
    // Name of the nib file
    static var nibName: String { get }
    func createFromNib( in bundle: Bundle ) -> NSView
}

extension NibLoadable where Self: NSView {
    // Default nib name must be same as class name
    static var nibName: String {
        return String( describing: Self.self )
    }

    func createFromNib( in bundle: Bundle = Bundle.main ) -> NSView {
        var topLevelArray: NSArray? = nil
        bundle.loadNibNamed( NSNib.Name( Self.nibName ), owner: self, topLevelObjects: &topLevelArray)
        if topLevelArray == nil { return NSView() }
        let views = Array<Any>(topLevelArray!).filter { $0 is NSView }
        return views.last as! NSView
    }
}

调用这个的代码:

private func commonInit() {
    let child = createFromNib()
    translatesAutoresizingMaskIntoConstraints = false
    addSubview( child )
}

相关问题