5

I would like to programmatically customize the UIButton. My code starts here:

class MyButton: UIButton {
    override func awakeFromNib() {
        super.awakeFromNib()

        layer.shadowRadius = 5.0
        ...
    }
}

Now I would like to define a constant width and height for the button, how to do it in code?

Leem.fin
  • 40,781
  • 83
  • 202
  • 354
  • did you try to use self.frame property ? – Prashant Tukadiya Sep 07 '17 at 11:25
  • 2
    First of all: don't. Use Autolayout when you can. Secondly, go through the documentation and you will see the available properties of `UIButton` immediately, the names tell you who to do it. – Dávid Pásztor Sep 07 '17 at 11:26
  • @DávidPásztor, But I have a unique style button apply across the whole project, using Autolayout means everywhere I have the button I need to set constraint for height. So, I think programmtically customize the button is better than auto layout in my case. – Leem.fin Sep 07 '17 at 11:27
  • So you actually want your custom button to have the same size on all screens, regardless whether the screen is of an iPhone SE or an iPad Pro 12.9? That's rarely a good idea. You can set Autolayout constraints programatically as well, so you don't need to do it every time again when you create a new button. – Dávid Pásztor Sep 07 '17 at 11:29
  • Possible duplicate of [How do I create a basic UIButton programmatically?](https://stackoverflow.com/questions/1378765/how-do-i-create-a-basic-uibutton-programmatically) – Prashant Tukadiya Sep 07 '17 at 11:38

4 Answers4

18

I would recommend to use autolayout:

class MyButton: UIButton {
    override func awakeFromNib() {
        super.awakeFromNib()

        layer.shadowRadius = 5.0

        // autolayout solution
        self.translatesAutoresizingMaskIntoConstraints = false
        self.widthAnchor.constraint(equalToConstant: 200).isActive = true
        self.heightAnchor.constraint(equalToConstant: 35).isActive = true
    }
} 
Milan Nosáľ
  • 19,169
  • 4
  • 55
  • 90
  • what is the difference between `self.heightAnchor.constraint(equalToConstant: 35).isActive = true` and `self.frame.size.height=35`? – Leem.fin Sep 07 '17 at 12:17
  • 2
    well, it's probably just a matter of taste, but I prefer to use autolayout constraints instead of directly setting the frame. according to [post][1] it is possible to combine autolayout with direct frame setting, however, I think it adds more complexity to the code (btw, if you are using nib to style the button, I would add those constraints in the nib as well, and not programmatically) [1]: https://stackoverflow.com/questions/13186908/can-i-use-setframe-and-autolayout-on-the-same-view – Milan Nosáľ Sep 07 '17 at 12:32
  • Beautiful stuff :) – Matthew Cawley Sep 21 '18 at 22:03
6

You need to override override init(frame: CGRect) method

class MyButton: UIButton {

    override init(frame: CGRect) {
        super.init(frame: frame)
        // Set your code here

        let width = 300
        let height = 50
        self.frame.size = CGSize(width: width, height: height)

        backgroundColor = .red
        layer.shadowRadius = 5.0
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }    
}
Govaadiyo
  • 5,644
  • 9
  • 43
  • 72
2

If your button is having constraints set from the storyboard as below and you want to change the width of the button, then this answer is helpful.

constraints set from the storyboard

Safe Area.trailing = Button.trailing + 20
Button.leading = Safe Area.leading + 20
Safe Area.bottom = Button.bottom + 20
height = 40
    

see the image for a better understanding.

enter image description here

Requirement :

if #condition 1 gets satisfied, then change button width to 100 or any width dimension.

else

if #condition 2 gets satisfied, then keep width as it is ( as per given constraints)

To handle this,

  1. Create an IBOutlet of leading and trailing constraints of that button.
  2. Set it to inactive.
  3. Add width anchor for the button programmatically.

Setting it inactive is mandatory because both won't work at the same time, so be careful.

@IBOutlet weak var btnNextTrailingConstraint: NSLayoutConstraint!
@IBOutlet weak var btnNextLeadingConstraint: NSLayoutConstraint!

if (condition1) {
  btnNextLeadingConstraint.isActive = false
  btnNextTrailingConstraint.isActive = false
  btnNext.widthAnchor.constraint(equalToConstant: 100).isActive = true
 }
 else {
   btnNextLeadingConstraint.isActive = true
   btnNextTrailingConstraint.isActive = true
 }


  

Shrikant Phadke
  • 358
  • 2
  • 11
2

I tried finding a way to create a square button box. Hope I`m not at the wrong place here, but when I tried to find my own solution it was as easy as this:

button.frame.size.width = 200
button.frame.size.height = 200

And this works of course with all the other views.