Ios Swift加载xib文件的正确方法
我在swift项目中加载xib文件时遇到了一些奇怪的问题。这太令人沮丧了,因为我已经知道如何在Obj-C中完成。但由于swift很快,所以你不能像以前那样完成/ 所以我创建了IconTextField.xib和IconTextField.swift。(扩展UITextField)在xib中,我在Idenity检查器中填充字段类,在故事板中,我对一些文本字段执行相同的操作。所以我们可以把加载从xib添加到init方法吗?没有 在objc中,我会这样做Ios Swift加载xib文件的正确方法,ios,swift,interface-builder,xib,Ios,Swift,Interface Builder,Xib,我在swift项目中加载xib文件时遇到了一些奇怪的问题。这太令人沮丧了,因为我已经知道如何在Obj-C中完成。但由于swift很快,所以你不能像以前那样完成/ 所以我创建了IconTextField.xib和IconTextField.swift。(扩展UITextField)在xib中,我在Idenity检查器中填充字段类,在故事板中,我对一些文本字段执行相同的操作。所以我们可以把加载从xib添加到init方法吗?没有 在objc中,我会这样做 - (instancetype)initWit
- (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;
}
所以我想如果我把它翻译成swift会很好
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let nib:NSArray = NSBundle.mainBundle().loadNibNamed("IconTextField", owner: self, options: nil)
self = nib.objectAtIndex(0)
}
但那是行不通的。我不知道为什么,但它试图创建更多的对象和崩溃
最后我找到了分机
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文件吗
更新
好,丹尼尔·安瑟之后
我当前的代码
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)
}
}
这两个变量连接到这些视图
Consoleo输出更大,最终以EXC\u BAD\u 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;>
2014-10-24 10:09:09.984测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:09.984测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:09.985测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:09.985测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:09.986测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:10.083测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:10.084测试项目[20337:3757479]使用编码器初始化
2014-10-24 10:09:10.084测试项目[20337:3757479]使用编码器初始化
它应该只有两个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:
,视图
和测试
按钮将按预期连接到插座。添加nib的视图自身的子视图层次结构使nib的内容可见。我更喜欢从nib加载,方法是在协议扩展中实现loadFromNib()
函数,如下所示:
(如本文所述:)
您可以使用以下选项:
if let customView = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as? MyCustomView {
// Set your view here with instantiated customView
}
这也是我在客观上一直做的,因为我只是更新了我的问题。我不知道我有什么不对劲。我只是在Xcode6.1中使用了您精确更新的代码(复制粘贴),效果很好。我还从println获得了非常不同的输出:
initWithCoder
输出很好。。我只是想让我们避免太多的文字:)你的故事板设置是什么?你能主持你的项目吗?为了测试,我在Obj-c中试了一下,反应是一样的。奇怪的是,这种加载xib只适用于UITableViewCell?我必须问一下。。。为什么要对UITextField
执行此操作?我见过它在UITableViewCells
上实现,但从来没有看到过文本字段。因为我想创建可重用的控件。例如,IconTextField
将UIImgaeView
作为图标。这样我就不必每次都附加UIImageView
。在我看来,这是最好的选择,我也这样做了(就像使用协议一样)。但是,您可以通过如下方式获取nib名称,对其进行一些小的更改,使其更加清晰:let nibName=“\(Self.Self)”
使用协议意味着您可以轻松地允许任何视图子类免费采用此功能,而无需继承
if let customView = Bundle.main.loadNibNamed("MyCustomView", owner: self, options: nil)?.first as? MyCustomView {
// Set your view here with instantiated customView
}