ios 从xib加载自定义视图后IBOutlet属性为零
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28384721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IBOutlet properties nil after custom view loaded from xib
提问by Gralex
Something strange going on with IBOutlets.
IBOutlets 发生了一些奇怪的事情。
In code I've try to access to this properties, but they are nil
. Code:
在代码中,我尝试访问此属性,但它们是nil
. 代码:
class CustomKeyboard: UIView {
@IBOutlet var aButt: UIButton!
@IBOutlet var oButt: UIButton!
class func keyboard() -> UIView {
let nib = UINib(nibName: "CustomKeyboard", bundle: nil)
return nib.instantiateWithOwner(self, options: nil).first as UIView
}
override init() {
super.init()
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
// MARK: - Private
private func commonInit() {
println(aButt)
// aButt is nil
aButt = self.viewWithTag(1) as UIButton
println(aButt)
// aButt is not nil
}
}
回答by fz.
That's expected, because the IBOutlet(s) are not assigned by the time the initializer is called. You don't need the commonInit, just an override of awakeFromNib as follows:
这是意料之中的,因为在调用初始化程序时尚未分配 IBOutlet。您不需要 commonInit,只需重写awakeFromNib,如下所示:
override func awakeFromNib() {
super.awakeFromNib()
print(aButt)
}
回答by ScottyBlades
Assuming you tried the standard troubleshooting steps for connecting IBOutlets, try this:
假设您尝试了连接 IBOutlets 的标准故障排除步骤,请尝试以下操作:
Apparently, you need to disable awake from nib in certain runtime cases.
显然,您需要在某些运行时情况下禁用从 nib 唤醒。
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
guard subviews.isEmpty else { return self }
return Bundle.main.loadNibNamed("MainNavbar", owner: nil, options: nil)?.first
}
回答by Josh O'Connor
Your nib may not be connected. My solution is quite simple. Somewhere in your project (I create a class called UIViewExtension.swift), add an extension of UIView with this handy connectNibUI method.
您的笔尖可能未连接。我的解决方案很简单。在您的项目中的某个地方(我创建了一个名为 UIViewExtension.swift 的类),使用这个方便的 connectNibUI 方法添加 UIView 的扩展。
extension UIView {
func connectNibUI() {
let nib = UINib(nibName: String(describing: type(of: self)), bundle: nil).instantiate(withOwner: self, options: nil)
let nibView = nib.first as! UIView
nibView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(nibView)
//I am using SnapKit cocoapod for this method, to update constraints. You can use NSLayoutConstraints if you prefer.
nibView.snp.makeConstraints { (make) -> Void in
make.edges.equalTo(self)
}
}
}
Now you can call this method on any view, in your init method, do this:
现在您可以在任何视图上调用此方法,在您的 init 方法中,执行以下操作:
override init(frame: CGRect) {
super.init(frame: frame)
connectNibUI()
}
回答by Chris Prince
Building on @ScottyBlades, I made this subclass:
基于@ScottyBlades,我创建了这个子类:
class UIViewXib: UIView {
// I'm finding this necessary when I name a Xib-based UIView in IB. Otherwise, the IBOutlets are not loaded in awakeFromNib.
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
guard subviews.isEmpty else { return self }
return Bundle.main.loadNibNamed(typeName(self), owner: nil, options: nil)?.first
}
}
func typeName(_ some: Any) -> String {
return (some is Any.Type) ? "\(some)" : "\(type(of: some))"
}
回答by szpetip
And how did you initiate your view from the controlller? Like this:
你是如何从控制器启动你的视图的?像这样:
var view = CustomKeyboard.keyboard()
self.view.addSubview(view)