如何在 iOS 中以编程方式设置纵横比约束?

我已经为我的视图控制器使用了自动布局。我已经设置了 V 和 H 位置的约束,但我想知道如何才能增加我的按钮大小时,它变化到5s,6和6 + 。这是我为登录按钮添加约束的方式:

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];

但我的问题是,虽然它管理左侧和右侧的差距,它得到伸展在 iPhone6和6 Plus,因为高度是固定的。如何根据屏幕大小增加尺寸?我认为这可能是纵横比,但是如何在代码中设置纵横比约束呢?

117434 次浏览

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))

You can set "Height constraint" at Design-time in Interface Builder. Just check '"Remove at build time", and it removes when App will running.

enter image description here After that you can add "Aspect Ratio" constraint, for example, in viewDidLoad method.

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]];

Swift 3:

yourView.addConstraint(NSLayoutConstraint(item: yourView,
attribute: .height,
relatedBy: .equal,
toItem: yourView,
attribute: .width,
multiplier: 9.0 / 16.0,
constant: 0))

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()

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:

Result view

Helper Extension on UIView

extension UIView {
    

func aspectRatio(_ ratio: CGFloat) -> NSLayoutConstraint {
        

return NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: self, attribute: .width, multiplier: ratio, constant: 0)
}
}

And usage is:

view.aspectRatio(1.0/1.0).isActive = true

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()