Search code examples
swiftuibuttonswift-extensions

How to create a global function that affects all or specific UIButton instance types?


I want to create a global function that affects either all UIButton instances or only those of a certain UIButton type which would update the corner radius or border property. I'm familiar with UIAppearances however my client would like to have a global file where they could update changes on the fly as if it were a CSS stylesheet. So far I've been able to make extensions of UIColor and UIFont which returns specific colors and fonts however I can't figure out how this would work for UIButton instances. Here is what I've thought of so far however I don't think this would work:

@objc extension UIButton {

    func changeUIButtonBorder() -> UIButton {
        self.layer.borderWidth = 3
        self.layer.borderColor = UIColor.white.cgColor
        return self
    }

}

Solution

  • What you're doing is great, and it does work for UIButton instances. But there is no need to return anything. In the extension, self is the button. So it can just change itself.

    @objc extension UIButton {
        func changeUIButtonBorder() {
            self.layer.borderWidth = 3
            self.layer.borderColor = UIColor.white.cgColor
        }
    }
    

    You can now call changeUIButtonBorder on any UIButton instance.

    @IBOutlet var myButton : UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        myButton.changeUIButtonBorder()
    }
    

    However, there is no magical way to shoutcast to all UIButtons that they should call that method; you'll have to deal with them one at a time.

    The "magical" way is, as @Sh_Khan suggests, to make a UIButton subclass that calls changeUIButtonBorder in its own initializer. You would then simply have to make sure that all your buttons are instances of that subclass.

    For example, here's a UIButton subclass that's always red (assuming that all instances come from the storyboard):

    class RedButton : UIButton {
        override func awakeFromNib() {
            super.awakeFromNib()
            self.backgroundColor = .red
        }
    }