我有一个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()
}
}
当前设置
在故事板上,目前,我已经添加了一个视图控制器,并且我在该视图控制器的视图中拖了一个UIView。之后,我将其自定义类设置为Hint
。此外,我使用@IBDesignable
指令并覆盖prepareForInterfaceBuilder()
以使所有内容都在设计中呈现,这一切都有效,直到我尝试为标签(hintLabel
)创建一个出口一个Hint.xib文件。
我收到下一个错误:
因未捕获的异常终止应用&#39; NSUnknownKeyException&#39;, 原因:&#39; [&lt; NSObject 0x60000001f8a0&gt; setValue:forUndefinedKey:]:this class不是键值hintLabel的密钥值编码。&#39;
我选择了我的Hint.xib文件 - &gt;文件的所有者,并检查身份检查器中的一切是否正常,看起来一切都很好:
通过IB或代码更改此标签文本的适当方法是什么。另外,我不能在Hint.xib中更改此标签的文本,因为我可能在屏幕上有多个视图来加载(来自)此xib,并且所有这些视图应该具有不同的文本。我想我在这里遗漏了一些明显的东西...感谢您的提示:))
答案 0 :(得分:3)
问题是你必须从&#34; owner:self&#34;中加载来自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)
答案 1 :(得分:3)
你所拥有的是非常接近工作。问题是您需要将所有者设置为提示视图,但您尝试在类方法中执行此操作。类方法中的self
是类,而您需要self
作为类的实例。您的fromNib
方法不需要是类方法,它可以是实例方法。这是一个例子:
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(){ //... }
。