如何从XIB实例访问视图

时间:2018-11-01 16:51:59

标签: ios xcode

我有一个.xib文件,其中包含一些不同的视图元素。现在,我在ViewController中用以下方法制作了它的几个实例:

UINib(nibName: "\(self)", bundle: nil).instantiate(withOwner: nil, options: nil).first

现在我不确定如何在UIView

中访问我的viewElements

我可以做myView.subviews()并遍历它们。但是,有什么办法可以使它们带有标签,以便例如可以直接从xib更改UITextField的文本吗?

1 个答案:

答案 0 :(得分:1)

您有一些选择。

第一个是将所有不相关的视图放在顶层,然后您可以通过其索引访问它们。例如,如果您依次拥有UIViewUITextFieldUILabel,则可以得到如下文本字段:

let textField = UINib(nibName: "\(self)", bundle: nil).instantiate(withOwner: nil, options: nil)[1] as? UITextField

第二个选项,如果要将视图保留为子视图,则将使用IBOutlets创建一个容器类作为其视图,将其设置为根视图的类,并连接出口,然后您将获得这样的文本字段

let textField = (UINib(nibName: "\(self)", bundle: nil).instantiate(withOwner: nil, options: nil).first as? ContainerClass)?.textFIeld

除了容器类,您还可以通过子视图的索引访问它们。

let textField = (UINib(nibName: "\(self)", bundle: nil).instantiate(withOwner: nil, options: nil).first as? UIView)?.subviews[1] as? TextField

另一种选择是使用泛型,此解决方案是Swifty的聪明选择,但仅在您仅具有给定类的一个视图时才有效。如果必须输入文本字段,它将返回第一个。

func findFirstElement<T>(of kind: T.Type, in array: [Any]) -> T? {
    for element in array {
        if let found = element as? T {
            return found
        }
    }
    return nil
}

您明白了。您可以按原样使用它,也可以使用UINib的扩展名来查找其内容,也可以使用UIView的扩展名来找到匹配的子视图。

有趣的是,该对象的返回值已经是您期望的类型,缺点是只能找到第一个对象。

我个人会使用第一个选项。如果视图不相关,则不会将它们添加为另一个视图的子视图。