子类化UIView

时间:2018-10-23 19:46:35

标签: swift class uiview subclass init

我正在尝试使用自定义初始化程序对UIView进行子类化,但是遇到多个错误。

class ProgressAlertView: UIView {

    var title: String

    override init(frame: CGRect) {
        super.init(frame: frame)
        alertLayout()
    }

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

    convenience init(title: String) {
        self.title = title
        self.init(title: title)
    }
}

上面的代码将导致多个错误消息,其中包括方便初始化中我的变量title的其他错误:在self.init调用之前在属性访问权title中使用的self本身。

但是,Swift要求在一个超类初始化所有实例变量之后必须调用超类中的所有初始化器。因此错误必须在其他地方。

高度赞赏这里的提示。

1 个答案:

答案 0 :(得分:1)

考虑一下您预期会发生什么……

override init(frame: CGRect) {
    super.init(frame: frame)
    alertLayout()
}

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

您有一个非可选的实例变量title。在这两种情况下应该如何获得价值?

在您的第三个init

convenience init(title: String) {
    self.title = title
    self.init(title: title)
}

init(title: String)调用init(title: String),依次调用init(title: String),依此类推。您位于无限递归区域。

如果要在代码中实例化视图,则需要类似...

init(title: String, frame: CGRect) {
    self.title = title
    super.init(frame: frame)
    alertLayout()
}

您还需要实现

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

如果您在情节提要/笔尖中使用此功能,那么您将需要...

required init?(coder aDecoder: NSCoder) {
    self.title = ""
    super.init(coder: aDecoder)
}

然后向title分配一个值