【问题标题】:Custom view's IBOutlet is nil自定义视图的 IBOutlet 为零
【发布时间】:2018-12-06 23:55:18
【问题描述】:

所以我有一个主要的viewController,它有一个堆栈视图,我想向其中添加我创建的自定义视图的多个实例。

所以我的想法是创建一个继承自UIView 的自定义视图。我希望视图始终为 40x40,所以我创建了一个新的 init 来处理这个问题? (不确定这是否正确):

class QuickAddView: UIView {

    @IBOutlet weak var iconLabel: UILabel!

    var task: Task = Task()

    public init(task: Task) {
        self.task = task
        super.init(frame: CGRect(x: 0, y: 0, width: 40, height: 40))

        configureView()
    }

    private func configureView() {
        self.layer.cornerRadius = self.frame.size.width / 2
        self.backgroundColor = task.color

        configureViewElements()
    }

    private func configureViewElements() {
        configureIconLabel()
    }

    private func configureIconLabel() {
        // CRASH: - iconLabel is nil here
        self.iconLabel.text = task.icon
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

}

然后我有一个 QuickAddView nib,它将其自定义类设置为 QuickAddView.swift

最后,我在 viewController 中创建自定义视图:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    configureViewElements()
}

private func configureViewElements() {
    configureQuickAddStackView()
}

private func configureQuickAddStackView() {
    let quickAddView = QuickAddView(task: Task(name: "Go to the store", icon: "????", color: .purple))

    quickAddStackView.addArrangedSubview(quickAddView)
}

我遇到的问题是当我尝试设置我的QuickAddView 时我的iconLabelnil。我也不知道我是否正在做这个创建自定义视图的过程是否正确。

【问题讨论】:

  • IBOutlet 是否连接到情节提要中的元素?

标签: swift uiview uiviewcontroller xib


【解决方案1】:

由于您是从 xibFile 连接 IBOutlet,因此您必须使用

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
    configureView()
}

在你的类中你也必须实例化它

if let quickAddView  = Bundle.mainBundle().loadNibNamed("QuickAddView", owner: self, options: nil).first as? QuickAddView {
 quickAddView.task = task
 }

【讨论】:

    【解决方案2】:

    问题是您在代码中创建了一个自定义视图,但对 iconLabel 使用了 IBOutlet。 IBOutlet 用于您在 Interface Builder 中构建的东西,而不是在代码中。如果要在代码中创建 QuickAddView,还需要在代码中的 QuickAddView 类中创建 iconLabel。您需要进行以下修改:

    weak var iconLabel: UILabel?
    
    private func configureIconLabel() {
        iconLabel = UILabel(frame: CGRect())
        if let iconLabel = iconLabel {
            iconLabel.text = task.icon
            addSubview(iconLabel)
        }
    }
    

    请注意,我传入了一个归零的 CGRect,但您需要使用任何您想要的 UILabel 原点和大小,或者使用自动布局来配置 iconLabel 的显示位置。

    【讨论】:

    • 所以你不能有一个自定义视图,其中也有 IBOutlets?或者您可以拥有它,但需要使用 nib 而不是 let quickView = QuickView() 来初始化自定义视图?我在这里有点困惑。
    • IBOutlets 严格用于使用 Interface Builder。你告诉编译器,“这个对象来自一个 xib 文件”,你需要将 IBOutlet 连接到 Interface Builder 中的视图才能工作。如果您想使用 Interface Builder,您可以将 QuickView 添加到 ViewController 的 xib 文件/情节提要场景中,向其中添加 UILabel,然后您必须连接出口。如果您对 Interface Builder 不满意,您只需省略 IBOutlet 关键字并在代码中执行所有操作,如上所示。
    • 这个答案显然是不正确的。 xib 文件可以与编程实例化混合使用。
    猜你喜欢
    • 2015-04-07
    • 2016-01-22
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 2013-11-05
    • 2017-06-08
    • 1970-01-01
    相关资源
    最近更新 更多