迅速正确的方式来加载xib文件

在swift项目中加载xib文件有一些奇怪的问题。 这太令人沮丧了,因为我已经知道如何在Obj-C中做到这一点。 但是,因为迅捷是快速的,所以你不能像你这样做。:/

所以我创build了IconTextFiled.xib和IconTextField.swift。 (扩展UITextField)在xib中,我填写Idenity检查器中的字段类和故事板中,我做一些textFields相同。 所以我们只需要从xib向init方法加载加载? 没有。

在objc我会这样做

- (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"IconTextField" owner:self options:nil]; self = [nib objectAtIndex:0]; } return self; } 

所以我想,如果我翻译的速度会很快。

 required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let nib:NSArray = NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil) self = nib.objectAtIndex(0) } 

但是,这没有用。 我不知道为什么,但它试图创造更多的对象和崩溃

最后我find了扩展

 extension IconTextField { class func loadFromNibNamed(nibNamed: String, bundle : NSBundle? = nil) -> IconTextField? { return UINib( nibName: nibNamed, bundle: bundle ).instantiateWithOwner(nil, options: nil)[0] as? IconTextField } } 

所以在ViewController中看起来像

 @IBOutlet var password: IconTextField! override func viewDidLoad() { super.viewDidLoad() password = IconTextField.loadFromNibNamed("IconTextField") } 

再次失败。 你能告诉我你如何加载和使用xib文件?

UPDATE

在Daniel anwser之后继续

我目前的代码

 class IconTextField: UITextField { @IBOutlet var icon: UIImageView! @IBOutlet weak var view: UIView! required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) NSLog("initWithCoder \(self)") NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil) self.addSubview(view) } } 

在这里输入图像说明

这两个var连接到这些意见

Consoleo输出很大,以EXC_BAD_ACCESS结束

 2014-10-24 10:09:09.984 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7bfb0;> 2014-10-24 10:09:09.984 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7ddf0;> 2014-10-24 10:09:09.985 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be7fa20;> 2014-10-24 10:09:09.985 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be814f0;> 2014-10-24 10:09:09.986 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7be830c0;> 2014-10-24 10:09:10.083 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d183270;> 2014-10-24 10:09:10.084 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d187cd0;> 2014-10-24 10:09:10.084 testproject[20337:3757479] initWithCoder <stensgroup.IconTextField: 0x7d189960;> 

它应该只有两个initWithCoder。 它接缝func loadNibNamed正在调用initWithCoder

这适用于我:

 class IconTextField: UITextField { @IBOutlet weak var view: UIView! @IBOutlet weak var test: UIButton! required init(coder: NSCoder) { super.init(coder: coder) NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil) self.addSubview(view) assert(test != nil, "the button is conected just like it's supposed to be") } } 

一旦loadNibNamed:owner:options:被调用, viewtestbutton按照预期连接到sockets。 添加笔尖的视图self的子视图层次结构使得笔尖的内容可见。

我更喜欢从nib加载,通过在协议扩展中实现loadFromNib()函数,如下所示:

(这里解释: https : //stackoverflow.com/a/33424509/845027 )

 import UIKit protocol UIViewLoading {} extension UIView : UIViewLoading {} extension UIViewLoading where Self : UIView { // note that this method returns an instance of type `Self`, rather than UIView static func loadFromNib() -> Self { let nibName = "\(self)".characters.split{$0 == "."}.map(String.init).last! let nib = UINib(nibName: nibName, bundle: nil) return nib.instantiateWithOwner(self, options: nil).first as! Self } } 

你可以使用这个:

 if let customView = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as? MyCustomView { // Set your view here with instantiated customView }