由于 nil 子视图,无法使用 Xib 文件创建自定义视图

Posted

技术标签:

【中文标题】由于 nil 子视图,无法使用 Xib 文件创建自定义视图【英文标题】:Cannot create a custom view using Xib file due to nil subviews 【发布时间】:2018-08-28 20:57:38 【问题描述】:

我有一个带有 5 个子视图的 XIB 文件。 XIB 设置为像这样的自定义类

class Slide: UIView 

    @IBOutlet weak var descriptionImage: UIImageView!
    @IBOutlet weak var descriptionLabel: UILabel!
    @IBOutlet weak var hiLabel: UILabel!
    @IBOutlet weak var loLabel: UILabel!
    @IBOutlet weak var humidityLabel: UILabel!


我像这样实例化let slide = Slide()

当我尝试设置变量时,即slide.descriptionLabel = "Hello"

我得到错误

线程 1:致命错误:在展开可选值时意外发现 nil

堆栈跟踪显示 XIB 已实例化,但子视图为零,因此无法设置。

【问题讨论】:

【参考方案1】:

这是因为你必须加载 nib 文件(这里我假设 nib 名称是 Slide

let slide  = Bundle.main.loadNibNamed("Slide", owner: nil, options: nil)![0] as! Slide

这样

let slide = Slide()

加载没有布局的视图,所以所有附加的视图都是nil

【讨论】:

【参考方案2】:

当您使用 Xibs 处理自定义视图时,您应该先加载它们。

因此,例如,在您的 Slide 类中,您可以创建如下静态函数:

static func createView(with owner: Any) -> Slide 
    let nib = UINib.init(nibName: "YourNibName", bundle: nil)
    let views = nib.instantiate(withOwner: owner, options: nil)
    let view = views[0] as! Slide
    view.translatesAutoresizingMaskIntoConstraints = false
    return view

YourNibName 应该是您的 Xib 文件的名称。

这个静态函数可以像这样使用:

let slide = Slide.createView(with: self)

// attach the view to a superview
aSuperview.addSubview(slide)

// setup the right constraints
// for example
slide.topAnchor.constraint(equalTo: aSuperview.topAnchor).isActive = true
// ...and so on

然后重要的是在 Interface Builder 中为您的 Xib 设置正确的视图:

回顾一下你的观点应该是这样的(注意我将Slide重命名为SlideView。听起来更好):

class SlideView: UIView 
    @IBOutlet var descriptionImage: UIImageView!
    @IBOutlet var descriptionLabel: UILabel!
    @IBOutlet var hiLabel: UILabel!
    @IBOutlet var loLabel: UILabel!
    @IBOutlet var humidityLabel: UILabel!

    static func createView(with owner: Any) -> SlideView 
        let nib = UINib.init(nibName: "YourNibName", bundle: nil)
        let views = nib.instantiate(withOwner: owner, options: nil)
        let view = views[0] as! SlideView
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    

【讨论】:

以上是关于由于 nil 子视图,无法使用 Xib 文件创建自定义视图的主要内容,如果未能解决你的问题,请参考以下文章

如何继承具有 .xib 文件的自定义视图

Swift - 带有 xib 文件的自定义视图,IBOutlet 为 nil

自定义 tableview 单元 xib 出口返回 nil

从 xib 添加自定义视图作为子视图时,UITableViewCell 的高度错误

将 xib 中的子视图添加到自定义 UIView

来自 XIB 的自定义 UIView 加载具有巨大规模的子视图