如何在iOS中以编程方式设置宽高比限制?

IRD*_*IRD 64 constraints ios autolayout nslayoutconstraint

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

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];
Run Code Online (Sandbox Code Playgroud)

但我的问题是,虽然它管理左侧和右侧间隙,但由于高度固定,它在iPhone 6和6 Plus中得到了拉伸.如何根据屏幕尺寸增加尺寸?我认为这可能是宽高比,但我如何在代码中设置宽高比约束?

Mah*_*wal 73

像这样.试试一次.

[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]];
Run Code Online (Sandbox Code Playgroud)

或代替(self.yourview.frame.size.height / self.yourview.frame.size.width)你可以使用任何浮动值.谢谢.

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))
Run Code Online (Sandbox Code Playgroud)

  • 在以编程方式设置任何约束之前,不要忘记添加此行:`[self.yourview setTranslatesAutoresizingMaskIntoConstraints:NO];` (3认同)
  • 这意味着在场景中,如果高度为100且宽度为200,并且您使用我的代码给出乘数0.5,那么如果您的高度将通过更改任何其他约束而增加到150,则宽度将自动增加到300.但是要做到这一点,您需要增加视图的一个约束,如宽度或高度. (2认同)
  • 它将需要高度:宽度 = 1:2,即 0.5。 (2认同)
  • 使用约束时,我的帧大小都为零。为了获得纵横比,我使用了`self.yourview.intrinsicContentSize` (2认同)

Eug*_*sov 56

布局锚点是以编程方式设置约束的最便捷方式.

假设您要为按钮设置5:1的宽高比,那么您应该使用:

button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1.0/5.0).isActive = true
Run Code Online (Sandbox Code Playgroud)

这是完整的代码:

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
    }

}
Run Code Online (Sandbox Code Playgroud)

这是使用上面编写的代码实现的结果.您可以看到该按钮在各种设备上保持5:1的宽高比:

结果视图


RNH*_*TTR 13

斯威夫特3:

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

  • 对于 iOS 8 及更高版本,您应该使用 NSLayoutConstraint 的 isActive 属性而不是调用 addConstraint(:)。`aspectRatioConstraint.isActive = true` (2认同)
  • 为什么不使用 `.width` 作为第一个属性?结果是`attr2 * multiplier`,宽高比是`width / height`,所以`width = height * aspectRatio`,如果我们把`.height`放在第一个属性上,把`aspectRatio`放在`multiplier`上那么结果就完全相反了。 (2认同)

Zan*_*ael 11

您可以在Interface Builder中的设计时设置"高度约束".只需选中"在构建时删除",它将在App运行时删除.

在此输入图像描述 之后,您可以在viewDidLoad方法中添加"Aspect Ratio"约束.

在Xamain.iOS中,对于"16:9",它看起来像这样:

    this.ImageOfTheDay.AddConstraint(NSLayoutConstraint.Create(
            this.ImageOfTheDay,
            NSLayoutAttribute.Height,
            NSLayoutRelation.Equal,
            this.ImageOfTheDay,
            NSLayoutAttribute.Width,
            9.0f / 16.0f,
            0));
Run Code Online (Sandbox Code Playgroud)

或者,正如Mahesh Agrawal所说:

    [self.ImageOfTheDay addConstraint:[NSLayoutConstraint
                              constraintWithItem:self.ImageOfTheDay
                              attribute:NSLayoutAttributeHeight
                              relatedBy:NSLayoutRelationEqual
                              toItem:self.ImageOfTheDay
                              attribute:NSLayoutAttributeWidth
                              multiplier:(9.0f / 16.0f)
                              constant:0]];
Run Code Online (Sandbox Code Playgroud)


Ale*_*cci 6

Swift 5 解决方案,Xcode 12.4。需要 iOS 9.0+

只需将您的高度限制固定为一定的比例即可:

let aspectRatio: CGFloat = 9 / 16 // Example of ratio you want to apply
yourView.heightAnchor.constraint(equalTo: imageView.widthAnchor,
                                 multiplier: aspectRatio).isActive = true
Run Code Online (Sandbox Code Playgroud)


tua*_*pen 5

我已经尝试了上面的所有答案,但没有成功,这是我使用 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()
Run Code Online (Sandbox Code Playgroud)


Mic*_*bro 5

UIView上的辅助扩展

extension UIView {

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

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

用法是:

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

  • 这确实是一个优雅的解决方案,除了几种类型: 1. toItem 参数设置为 `.self` 而不是 `self` 2. 注释中的用法应该是 `view.aspectRation(1.0/1.0).isActive = true ` 我在 Xcode 10.2.1 Swift 5 中对此进行了测试。 (2认同)