使用 IBOutlets 正确设置 UIView 子类
Properly setup UIView subclass with IBOutlets
背景
我在我的 class MyView
中 class 编辑了 UIView
。我创建了附加到子 class 的 IBOutlet
s。当调用 setup()
方法从 init()
进行一些设置时,我发现插座尚未初始化,因此 nil
.
我尝试覆盖有效的 layoutSubviews()
,但正如我所读,在将新视图添加为子视图后,每次 都会调用 layoutSubviews()
,因此这似乎不是最佳实践。
我想到了这个解决方案:单独调用 setup()
- 不是在 class 中,而是在 ViewController
MyView
的 viewDidLoad()
中是的。这似乎有效,但我认为相当不方便。
代码
这是我的代码的简短摘要:
class MyView: UIView {
@IBOutlet weak var button: UIButton!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup() {
if button == nil { print("nil") } //prints "nil"
}
}
问题
本质上,问题是 在 class 内部我应该调用 setup()
方法。
您的设置需要进入 awakeFromNib
而不是 init
override func awakeFromNib() {
super.awakeFromNib()
// Your setup here
setup()
}
awakeFromNib
在视图从 nib 加载后调用,并且在所有插座等已连接后调用。 init(coder:)
在创建视图后调用,但尚未创建/连接其余视图。
但是,使用 init(frame:)
创建视图意味着 awakeFromNib
不会被调用 (真的很明显 - 这个里面没有 nib案例!)因此您可能还必须在其中放置一些设置代码 - 完全取决于您的用例。
背景
我在我的 class MyView
中 class 编辑了 UIView
。我创建了附加到子 class 的 IBOutlet
s。当调用 setup()
方法从 init()
进行一些设置时,我发现插座尚未初始化,因此 nil
.
我尝试覆盖有效的 layoutSubviews()
,但正如我所读,在将新视图添加为子视图后,每次 都会调用 layoutSubviews()
,因此这似乎不是最佳实践。
我想到了这个解决方案:单独调用 setup()
- 不是在 class 中,而是在 ViewController
MyView
的 viewDidLoad()
中是的。这似乎有效,但我认为相当不方便。
代码
这是我的代码的简短摘要:
class MyView: UIView {
@IBOutlet weak var button: UIButton!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup() {
if button == nil { print("nil") } //prints "nil"
}
}
问题
本质上,问题是 在 class 内部我应该调用 setup()
方法。
您的设置需要进入 awakeFromNib
而不是 init
override func awakeFromNib() {
super.awakeFromNib()
// Your setup here
setup()
}
awakeFromNib
在视图从 nib 加载后调用,并且在所有插座等已连接后调用。 init(coder:)
在创建视图后调用,但尚未创建/连接其余视图。
但是,使用 init(frame:)
创建视图意味着 awakeFromNib
不会被调用 (真的很明显 - 这个里面没有 nib案例!)因此您可能还必须在其中放置一些设置代码 - 完全取决于您的用例。