如何使用自动布局“项目格式约束”为 UIViews 设置相等的宽度

Posted

技术标签:

【中文标题】如何使用自动布局“项目格式约束”为 UIViews 设置相等的宽度【英文标题】:How to set equal widths for UIViews using auto-layouts "Constraint with item format" 【发布时间】:2015-09-09 16:06:24 【问题描述】:

在我的应用程序中,我在视图控制器上插入了 UIView。我的主要要求是我想使用自动布局“项目格式约束”为两个 UIView 设置相等的宽度。

为此,我编写了一些代码,但没有得到相等的宽度。我在这里做错了什么?

我想得到如下图所示的结果(即需要为两个 UIView 设置相等的宽度)。

我的代码:

#import "ViewController8.h"

@interface ViewController8 ()

    UIView * myView1;
    UIView * myView2;

@end

@implementation ViewController8

- (void)viewDidLoad 
    [super viewDidLoad];

    myView1 = [[UIView alloc] init];
    myView1.backgroundColor = [UIColor lightGrayColor];
    myView1.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:myView1];

    myView2 = [[UIView alloc] init];
    myView2.backgroundColor = [UIColor redColor];
    myView2.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:myView2];

    [self operation2];


-(void)operation2

    //Applying autolayouts for myview2

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
                                                          attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:nil
                                                          attribute:0
                                                         multiplier:1.0
                                                           constant:50]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
                                                          attribute:NSLayoutAttributeTrailing
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeTrailing
                                                         multiplier:1.0
                                                           constant:-10]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
                                                          attribute:NSLayoutAttributeBottom
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1.0
                                                           constant:-30]];

    //Applying autolayouts for myview1

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
                                                          attribute:NSLayoutAttributeLeading
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeLeading
                                                         multiplier:1.0
                                                           constant:10]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
                                                          attribute:NSLayoutAttributeHeight
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:nil
                                                          attribute:0
                                                         multiplier:1.0
                                                           constant:50]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
                                                          attribute:NSLayoutAttributeTrailing
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:myView2
                                                          attribute:NSLayoutAttributeLeading
                                                         multiplier:1.0
                                                           constant:-30]];

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
                                                          attribute:NSLayoutAttributeBottom
                                                          relatedBy:NSLayoutRelationEqual
                                                             toItem:self.view
                                                          attribute:NSLayoutAttributeBottom
                                                         multiplier:1.0
                                                           constant:-30]];

【问题讨论】:

【参考方案1】:

您发布的代码中不存在等宽约束。试试添加这个

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView1
  attribute:NSLayoutAttributeWidth 
  relatedBy:NSLayoutRelationEqual 
  toItem:nil 
  attribute:NSLayoutAttributeNotAnAttribute 
  multiplier:1.0 
  constant:200]];


[self.view addConstraint:[NSLayoutConstraint constraintWithItem:myView2
  attribute:NSLayoutAttributeWidth 
  relatedBy:NSLayoutRelationEqual 
  toItem:myView1
  attribute:NSLayoutAttributeWidth 
  multiplier:1.0 
  constant:0]];

【讨论】:

显式宽度约束会导致约束冲突,因为view1view2 是水平固定的。【参考方案2】:

加上等宽约束就够了

[NSLayoutConstraint constraintWithItem:myView1
                             attribute:NSLayoutAttributeWidth
                             relatedBy:NSLayoutRelationEqual
                                toItem:myView2
                             attribute:NSLayoutAttributeWidth
                            multiplier:1.0
                              constant:0];

不得使用约束显式定义两个视图的宽度,因为view1 固定在父视图的前沿,view2 固定在父视图的后沿,并且view1 的后沿固定到 view2 的前沿。因此,加入上述等宽约束后,约束系统就完全确定了。

这就是添加约束将导致的结果:

【讨论】:

【参考方案3】:

当代解决方案是使用NSLayoutAnchor

myView1.widthAnchor.constraint(equalTo: myView2.widthAnchor)

别忘了使用isActive = trueNSLayoutConstraint.activate() 激活它。

【讨论】:

以上是关于如何使用自动布局“项目格式约束”为 UIViews 设置相等的宽度的主要内容,如果未能解决你的问题,请参考以下文章

如何垂直自动布局 UIViews 列表,一个在彼此之上?

UIViews 的高度与屏幕的高度成比例(自动布局)

是否可以定义相对于未知 UIViews 的自动布局约束?

遇到 NSLayoutConstraints 问题并以编程方式使用自动布局时,UIViews 停留在 (0,0)

如何以编程方式使用自动布局以编程方式添加 UIview?

当我结合 UIPanGestureRecognizer 和自动布局时,我的 UIViews 搞砸了