从 xib 文件中为对象创建出口
Making outlet for the object from a xib file
我有一个 Hint.xib 文件,其中只有很少的元素(标签、图像视图和按钮)。我有一个名为 Hint 的 class,它是 UIView 的子class,它加载了这个 xib。
提示 class 的实现方式如下:
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 拖到该视图控制器的视图中。之后,我将其自定义 class 设置为 Hint
。此外,我正在使用 @IBDesignable
指令并覆盖 prepareForInterfaceBuilder()
以在设计中呈现所有内容,这一切都有效,直到我尝试为作为一部分的标签 (hintLabel
) 制作出口Hint.xib 文件。
我遇到下一个错误:
Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[< NSObject 0x60000001f8a0 > setValue:forUndefinedKey:]: this
class is not key value coding-compliant for the key hintLabel.'
我已经选择了我的 Hint.xib 文件 -> 文件的所有者,并在 Identity Inspector 中检查了一切是否正常,看起来一切正常:
通过 IB 或代码更改此标签文本的合适方法是什么?此外,我不能只在 Hint.xib 中更改此标签的文本,因为我可能在一个屏幕上有多个视图加载(从)此 xib,并且所有这些视图都应该有不同的文本。我想我在这里遗漏了一些明显的东西...感谢您的提示 :))
问题是您必须使用 "owner:self" 从捆绑包中加载 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 文件(不是 UIView)中将文件所有者设置为提示 class
你所拥有的非常接近工作。问题是您需要将所有者设置为提示视图,但您正试图在 class 方法中执行此操作。 class 方法中的 self
是 class,而您需要 self
成为 class 的 实例 .您的 fromNib
方法不必是 class 方法,它可以是实例方法。这是一个例子:
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(){ //... }
。
我有一个 Hint.xib 文件,其中只有很少的元素(标签、图像视图和按钮)。我有一个名为 Hint 的 class,它是 UIView 的子class,它加载了这个 xib。
提示 class 的实现方式如下:
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 拖到该视图控制器的视图中。之后,我将其自定义 class 设置为 Hint
。此外,我正在使用 @IBDesignable
指令并覆盖 prepareForInterfaceBuilder()
以在设计中呈现所有内容,这一切都有效,直到我尝试为作为一部分的标签 (hintLabel
) 制作出口Hint.xib 文件。
我遇到下一个错误:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[< NSObject 0x60000001f8a0 > setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key hintLabel.'
我已经选择了我的 Hint.xib 文件 -> 文件的所有者,并在 Identity Inspector 中检查了一切是否正常,看起来一切正常:
通过 IB 或代码更改此标签文本的合适方法是什么?此外,我不能只在 Hint.xib 中更改此标签的文本,因为我可能在一个屏幕上有多个视图加载(从)此 xib,并且所有这些视图都应该有不同的文本。我想我在这里遗漏了一些明显的东西...感谢您的提示 :))
问题是您必须使用 "owner:self" 从捆绑包中加载 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 文件(不是 UIView)中将文件所有者设置为提示 class
你所拥有的非常接近工作。问题是您需要将所有者设置为提示视图,但您正试图在 class 方法中执行此操作。 class 方法中的 self
是 class,而您需要 self
成为 class 的 实例 .您的 fromNib
方法不必是 class 方法,它可以是实例方法。这是一个例子:
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(){ //... }
。