Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift加载xib文件的正确方法_Ios_Swift_Interface Builder_Xib - Fatal编程技术网

Ios Swift加载xib文件的正确方法

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

我在swift项目中加载xib文件时遇到了一些奇怪的问题。这太令人沮丧了,因为我已经知道如何在Obj-C中完成。但由于swift很快,所以你不能像以前那样完成/

所以我创建了IconTextField.xib和IconTextField.swift。(扩展UITextField)在xib中,我在Idenity检查器中填充字段类,在故事板中,我对一些文本字段执行相同的操作。所以我们可以把加载从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;
}
所以我想如果我把它翻译成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
}