I have used auto layout for my view controllers. I have set the V and H positions in constraints, but I want to know how can I increase my button size when it changes to 5s, 6 and 6 Plus. This is the way I added constraints for the login button:
NSArray *btncon_V=[NSLayoutConstraint constraintsWithVisualFormat:@"V:[btnLogin(40)]" options:0 metrics:nil views:viewsDictionary];
[btnLogin addConstraints:btncon_V];
NSArray *btncon_POS_H=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[btnLogin]-100-|" options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:btncon_POS_H];
NSArray *btncon_POS_V=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-70-[Title]-130-[lblFirst]-0-[lblSecond]-20-[textusername]-10-[txtpassword]-10-[btnLogin]" options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:btncon_POS_V];
But my problem is that while it manages the left and right side gap, it's getting stretched in iPhone 6 and 6 Plus since the height is fixed. How can I increase the size according to the screen size? I think this might be the aspect ratio, but how can I set the aspect ratio constraint in code?
Layout Anchors is the most convenient way to set constraints programmatically.
Say you want to set 5:1 aspect ratio for your button then you should use:
button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0/5.0).isActive = true
Here's the full code:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .custom)
button.setTitle("Login", for: .normal)
button.backgroundColor = UIColor.darkGray
self.view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
let margins = view.layoutMarginsGuide
button.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20.0).isActive = true
button.trailingAnchor.constraint(equalTo: margins.trailingAnchor, constant: -20.0).isActive = true
button.bottomAnchor.constraint(equalTo: margins.bottomAnchor, constant: -20.0).isActive = true
button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0/5.0).isActive = true
}
}
Here're results achieved with code written above. You can see that button keeps its 5:1 aspect ratio across various devices:
https://i.stack.imgur.com/cTqM1.png
Like this. Try once.
[self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.yourview addConstraint:[NSLayoutConstraint
constraintWithItem:self.yourview
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.yourview
attribute:NSLayoutAttributeWidth
multiplier:(self.yourview.frame.size.height / self.yourview.frame.size.width)
constant:0]];
or in the place of (self.yourview.frame.size.height / self.yourview.frame.size.width)
you can use any float value. Thanks.
Swift 3.0 -
self.yourview!.translatesAutoresizingMaskIntoConstraints = false
self.yourview!.addConstraint(NSLayoutConstraint(item: self.yourview!,
attribute: NSLayoutAttribute.height,
relatedBy: NSLayoutRelation.equal,
toItem: self.yourview!,
attribute: NSLayoutAttribute.width,
multiplier: self.yourview.frame.size.height / self.yourview.frame.size.width,
constant: 0))
[self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];
self.yourview.intrinsicContentSize
Swift 3:
yourView.addConstraint(NSLayoutConstraint(item: yourView,
attribute: .height,
relatedBy: .equal,
toItem: yourView,
attribute: .width,
multiplier: 9.0 / 16.0,
constant: 0))
aspectRatioConstraint.isActive = true
.width
as the first attribute? The result is attr2 * multiplier
, the aspect ratio is width / height
, so width = height * aspectRatio
, if we put the .height
to the first attribute and the aspectRatio
to the multiplier
then the result is totally reversed.
You can set "Height constraint" at Design-time in Interface Builder. Just check '"Remove at build time", and it removes when App will running.
https://i.stack.imgur.com/fqhSi.png
In Xamain.iOS for "16:9" it's looks like this:
this.ImageOfTheDay.AddConstraint(NSLayoutConstraint.Create(
this.ImageOfTheDay,
NSLayoutAttribute.Height,
NSLayoutRelation.Equal,
this.ImageOfTheDay,
NSLayoutAttribute.Width,
9.0f / 16.0f,
0));
Or, as Mahesh Agrawal said:
[self.ImageOfTheDay addConstraint:[NSLayoutConstraint
constraintWithItem:self.ImageOfTheDay
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:self.ImageOfTheDay
attribute:NSLayoutAttributeWidth
multiplier:(9.0f / 16.0f)
constant:0]];
Helper Extension on UIView
extension UIView {
func aspectRation(_ ratio: CGFloat) -> NSLayoutConstraint {
return NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: self, attribute: .width, multiplier: ratio, constant: 0)
}
}
And usage is:
view.aspectRation(1.0/1.0).isActive = true
.self
instead of self
2. And the usage in comment should be view.aspectRation(1.0/1.0).isActive = true
I tested this in Xcode 10.2.1 Swift 5.
I have try all answers above but didn't work, and this is my solution with swift 3:
let newConstraint = NSLayoutConstraint(item: yourView, attribute: .width, relatedBy: .equal, toItem: yourView, attribute: .height, multiplier: 560.0/315.0, constant: 0)
yourView.addConstraint(newConstraint)
NSLayoutConstraint.activate([newConstraint])
NSLayoutConstraint.deactivate(yourView.constraints)
yourView.layoutIfNeeded()
Swift 5 solution, Xcode 12.4. Requires ios 9.0+
Simply anchor your height constraint to a certain ratio:
let aspectRatio: CGFloat = 9 / 16 // Example of ratio you want to apply
yourView.heightAnchor.constraint(equalTo: imageView.widthAnchor,
multiplier: aspectRatio).activate()
Success story sharing