Home > Mobile >  How to subclass a UIButton with its primaryAction initializer
How to subclass a UIButton with its primaryAction initializer

Time:10-27

We can initialize a new UIButton this way:

// myAction is a var of type UIAction
let btn = UIButton(primaryAction: myAction)

So I'm thinking cool, I can subclass this and stop using target-action. But here's the problem, Xcode can't seem to recognize the primaryAction initializer.

class Button: UIButton {
    init(type: String, action: UIAction) {
        super.init(primaryAction: action) // Error "Must call a designated initializer of the superclass 'UIButton'"
    }
}

So it's not a designated initializer. How can I access this primaryAction property inside a UIButton subclass?

CodePudding user response:

Because you can't initialize a superclass within a custom initializer with one of its convenience initializers, you have to perform the tasks of that convenience init manually. So after you've initialized the superclass with one of its designated inits:

class Button: UIButton {
    init(type: String, action: UIAction) {
        super.init(frame: .zero)
        
        // register the action for the primaryActionTriggered control event
        // and set the title and image properties to the action’s title and image
    }
}

And it's not as straightforward as changing the value of a single property.

You set up a control so that it sends an action message to a target object by associating both target and action with one or more control events. To do this, send addTarget(_:action:for:): to the control for each Target-Action pair you want to specify.

https://developer.apple.com/documentation/uikit/uicontrol/event

CodePudding user response:

I figured it out. We can use addAction instead of addTarget. Requires iOS 14 .

func addAction(_ action: UIAction, for controlEvents: UIControl.Event) is available on all subclass of UIControl. Meaning we no longer have to scatter targets and @objc func all over our code. Just add a UIAction to your control.

class Button: UIButton {
    init(type: String, action: UIAction) {
        super.init(frame: .zero)
        addAction(action, for: .touchUpInside)
    }
}
  • Related