I know this is a silly example, but it's the smallest one I could think of that demonstrates my problems.
Let's say I have a Swift 5 project with some UI Buttons in it. As background, this project doesn't use storyboards, and where possible I don't specify frames for subviews, as everything is positioned with the various .constraint() methods. Also, let's say all of my buttons are declared in one of these two ways:
let yellowButton = UIButton()
yellowButton.setTitleColor(.yellow, for: .normal)
let blueButton = UIButton()
blueButton.setTitleColor(.blue, for: .normal)
I decide that I want to compact this, by creating a subclass of UIButton that I can construct as let yellowButton = MyButton(isYellow: true), since there are only two colors. I've tried to write something like this:
import UIKit
class MyButton: UIButton {
private var isYellow: Bool
required init?(coder: NSCoder) {
fatalError("Not using storyboards")
}
init(isYellow: Bool) {
self.isYellow = isYellow
super.init() // <-- Compile error here
}
// ... code to handle color automatically ...
}
However, it doesn't let me call super.init(). It gives me the options of super.init(coder:), super.init(frame:), super.init(type:), super.init(frame:primaryAction:), and super.init(type:primaryAction:). None of these seem particularly like what I want. Since I'm using constraints to position it, I suppose I could call init(frame:) with an arbitrary constant CGRect, but semantically that seems odd. I have two questions about this:
- Why can I call
UIButton()in my view controllers, but notsuper.init()in a subclass of UIButton? - What's the best way to handle this situation, and more generally, what should I do when none of the superclass's initializers seem appropriate?