无法继承UIButton:必须调用超类'UIButton'的指定初始化程序

13

试图对UIButton进行子类化,但出现错误必须调用超类 'UIButton' 的指定初始化程序

查阅了几篇Stack Overflow帖子像这样的这个这个或其他几个都没有帮助,因为这些解决方案不起作用。

我们如何在Swift中对UIButton进行子类化并定义自定义init函数呢?

import UIKit

class KeyboardButton : UIButton {
    var letter = ""
    var viewController:CustomViewController?

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

    init(letter: String, viewController: CustomViewController) {
        super.init()
        ...
    }
}

1
由于错误提示,您无法调用 super.init() 因为它不是指定的初始化程序。您需要调用 super.init(frame:frame),这意味着您需要向初始化程序提供一个框架。话虽如此,这看起来相当糟糕。您应该实现委托模式,而不是向初始化程序提供视图控制器。 - Paulw11
好主意 @Paulw11,感谢您的建议。我是Swift的新手,所以非常感激您的建议。 - Crashalot
1个回答

23

你需要调用父类的指定初始化器:

Swift 3和4:

init(letter: String, viewController: CustomViewController) {
    super.init(frame: .zero)
}

Swift 1 & 2:

init(letter: String, viewController: CustomViewController) {
    super.init(frame: CGRectZero)
}

正如Paulw11在评论中所说,一个视图通常不应该引用它的控制器,除非使用委托模式作为弱引用,这将促进可重用性。


谢谢!我是Swift的新手,所以委托模式是一个很好的建议。似乎使用CGRectZero作为初始框架只是为了稍后更改它有些hackish。没有办法使用没有参数的初始化器吗?感谢您的帮助! - Crashalot
4
指定初始化方法有一个非可选参数,因此没有办法不传参调用它。如果你感到更好的话,init() 只是一个方便的初始化器,它会调用 init(frame: CGRectZero) - Aaron Brager
但是在子类中如何设置按钮类型? - Tod Cunningham
@TodCunningham,由于Swift的严格类型安全性,您无法以完全相同的方式执行此操作。请参阅https://dev59.com/nGAg5IYBdhLWcg3wDHfS了解其他方法。 - Aaron Brager

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接