简体   繁体   中英

How do I programatically resize a UIButton that already has constraints?

I have a UIButton that I have set to sit 8 points from the left and 8 points from the bottom of my view. I currently have the width and height set to >= 32 points.

But, I want the button to be larger on larger displays. I worked out how to set constraints so that the button is always at the same aspect ratio (square in my case) and always 10% of the width of its parent view, but that means when a device is rotated the button gets bigger and smaller as the view gets wider and narrower and I don't want that. I want it to be 10% of the shortest side.

It's easy in the enclosing ViewController code to get my desired width:

let buttonWidth = 0.1 * (self.view.bounds.width < self.view.bounds.height ? self.view.bounds.width : self.view.bounds.height)

But how do I correctly apply this to the button and what constraints should be in place from the storyboard? The entire interface is currently defined in the storyboard.

Do I update the bounds directly? A constraint? Multiple constraints? In the case of constraints I am completely unfamiliar with how deal with them in code.

Achieving what you want, can't be done using only storyboard because you want to choose the smallest side of the screen and get 10% of it. In code you can easily do that.

  1. First you need to make IBOutlet of your width constraint. See this answer for detailed explanation
  2. Then change the constant of your IBOutlet width constraint depending on you calculated size. As far as you have aspect ratio 1:1 it will automatically change height equal width.


let buttonWidth = 0.1 * min(self.view.bounds.width, self.view.bounds.height)

self.yourWidthConstraint.constant = buttonWidth

self.view.layoutIfNeeded()

Try this:

your_button.frame.size.width = buttonWidth

Or you can add/change constraint:

let widthConstraint = NSLayoutConstraint (item: your_button, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: buttonWidth)
your_button.view.addConstraint(widthConstraint)

I think you should explore the size classes APIs by Apple. You can set the constraints for your button for all specific cases, ie smaller and larger devices, portrait and landscape, right in Interface Builder.

More details here: About Designing for Multiple Size Classes

Edit : If you want to keep the same widht/height when device is rotated, forget about width constraint in storyboard (but keep the aspect ratio one). Create width constraint programmatically like this:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // Equivalent: Width of self.button equals 0.1 * width of self.view
    let widthConstraint = NSLayoutConstraint(item: self.button,
                                        attribute: NSLayoutAttribute.Width,
                                        relatedBy: NSLayoutRelation.Equal,
                                           toItem: nil,
                                        attribute: NSLayoutAttribute.NotAnAttribute,
                                       multiplier: 1.0,
                                         constant: 0.1 * CGRectGetWidth(self.view.bounds))

    self.view.addConstraint(widthConstraint)
    self.view.layoutIfNeeded()
}

It won't get wider and narrower if you create a width constrant and a aspect ratio constraint.

按钮约束

Ctrl + drag your button to content view, then choose Equals Width. Then edit that constraint with multiplier = 0.1. So your button width is always equals 10% of device width.

Then create a Aspect Ratio constraint and the button won't get narrower.

if your button have the constraints, you need to find it on this way:

button.superview?.constraints.forEach { constraint in
  if constraint.firstItem === button &&
     constraint.firstAttribute == .width {
     constraint.constant = 20
     return
  } 
}       
self.view.layoutIfNeeded() 

Or you can make an IBOutlet for your constraint and change the constant of it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM