Home > Enterprise >  Is there a way to set the buttonType of a custom button class in Swift (ex: setting the button type
Is there a way to set the buttonType of a custom button class in Swift (ex: setting the button type

Time:03-31

I have this custom button class below:

import UIKit
class CustomButton: UIButton {
    init(title: String) {
        super.init(frame: .zero)
        let height: CGFloat = 38
        setTitleColor(UIColor.white, for: .normal)
        setTitle(title, for: .normal)
        setDimensions(height: height, width: 120)
        layer.cornerRadius = height/7
        backgroundColor = .red
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

And here is the code in my controller to create a button using this class:

private let loginButton: UIButton = {
        let button = CustomButton(title: "Login")
        button.isEnabled = false
        button.addTarget(self, action: #selector(handleLogin), for: .touchUpInside)
        return button
    }()

I can't assign it a buttonType because buttonType is a get only property. Usually I just assign the buttonType by saying let button = UIButton(type: .system) but above, I'm creating the button by making it a button of the CustomButton class. How do I set a button type to this custom button class? Thanks.

CodePudding user response:

Since the button type is a get-only property, the only way to set it is to call the init(type:) initialiser. To call it, you can do something like this:

class CustomButton: UIButton {
    convenience init(title: String, type: UIButton.ButtonType = .system) {
        self.init(type: type)
        let height: CGFloat = 38
        setTitleColor(UIColor.white, for: .normal)
        setTitle(title, for: .normal)
        setDimensions(height: height, width: 120)
        layer.cornerRadius = height/7
        backgroundColor = .red
        self.buttonType
    }

    ...

}

Notice that init(type:) is a convenience initialiser, so it must be delegated from a convenience initialiser. This means that you can't initialise any of your stored properties in your init(title:type:), but it doesn't seem like you have any anyway. Stored properties can only be initialised in their property initialisers inline. It is also arguable whether a button with customisable stored properties like that can still be called a "system" type button.

Another thing to note is that since the class only has one convenience initialiser, it inherits all the initialisers from its superclass, hence why it is self.init(type: type) and not super.init(type: type), and why there is no need to declare the required initialiser.

  • Related