首页 文章

从xib文件中为对象创建插座

提问于
浏览
3

我有一个Hint.xib文件,其中我有几个元素(标签,图像视图和一个按钮) . 我有一个名为Hint的类,它是UIView的子类,它加载了这个xib .

以下是Hint类实现的外观:

import UIKit

@IBDesignable

extension UIView {
    class func fromNib<T : UIView>() -> T? {
        guard
            let nibs = Bundle(for: self).loadNibNamed(String(describing: self), owner: nil, options: nil),
            let nib = nibs.first
            else {
                return nil
        }

        return nib as? T
    }
}

class Hint:UIView {
    @IBOutlet weak var hintLabel: UILabel! 
    private func setup(){

        if let view = Hint.fromNib(){
            self.addSubview(view)
            view.frame = self.bounds
        }
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        setup()
    }


    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()

        setup()
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

       setup()
    }
}

Current Setup

在故事板上,目前,我是_786717的观点 . 之后,我将其自定义类设置为 Hint . 此外,我正在使用 @IBDesignable 指令并覆盖 prepareForInterfaceBuilder() 以在设计中呈现所有内容,这一切都有效,直到我尝试为Hint.xib文件的一部分标签( hintLabel )创建出口 .

我收到下一个错误:

由于未捕获的异常'NSUnknownKeyException'终止应用程序,原因:'[<NSObject 0x60000001f8a0> setValue:forUndefinedKey:]:此类不是键值hintLabel的键值编码兼容 .

我已经选择了我的Hint.xib文件 - >文件的所有者,并检查了Identity Inspector中是否一切正常,看起来一切都很好:

enter image description here

通过IB或代码更改此标签文本的适当方法是什么 . 此外,我不能只在Hint.xib中更改此标签的文本,因为我可能在屏幕上有多个视图来加载(来自)此xib,并且所有这些视图应该具有不同的文本 . 我想我在这里遗漏了一些明显的东西......谢谢你的暗示:))

2 回答

  • 3

    你所拥有的是非常接近工作 . 问题是您需要将所有者设置为提示视图,但您尝试在类方法中执行此操作 . 类方法中的 self 是类,而您需要 self 作为类的实例 . 你的 fromNib 方法没有't need to be a class method, it can be an instance method. Here'一个例子:

    extension UIView {
        func createView<T : UIView>() -> T? {
            let type = type(of:self)
            guard
                let nibs = Bundle(for: type).loadNibNamed(String(describing: type), owner: self, options: nil),
                let nib = nibs.last
                else {
                    return nil
            }
    
            return nib as? T
        }
    }
    

    现在在视图设置中,您可以使用 if let view = createView(){ //... } .

  • 2

    问题是您必须使用“owner:self”从bundle加载xib,所以它应该如下所示:

    class Hint:UIView {
        @IBOutlet var view: UIView!
        @IBOutlet weak var hintLabel: UILabel!
        private func setup(){
    
            Bundle.main.loadNibNamed("Hint", owner: self, options: nil)
            self.addSubview(view)
            view.frame = self.bounds
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            setup()
        }
    
    
        override func prepareForInterfaceBuilder() {
            super.prepareForInterfaceBuilder()
    
            setup()
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            setup()
        }
    }
    

    另外不要忘记在xib文件中设置文件所有者为Hint类(不是UIView)

相关问题