1

我有以下设置:

  1. 大小为 (40,40) 的 UIView
  2. 此视图的 3 个子视图,每个子视图都有框架 (0,0,40,40)

现在,我希望此设置始终保持以下约束:

H:|-10-[v1]-10-[v2]-10-[v3]-10-|

这意味着在 superview 的整个生命周期中需要以下行为:

  1. 设置约束后,视图应立即自动布局,如上所示。
  2. 由于 superview 本身只有 (40,40),它应该自动调整大小以使布局成为可能。
  3. 从那里开始,更改任何子视图的宽度应该再次布局视图,以便它们仍然坚持布局格式。

到目前为止,我的方法是这样的:

- (id)init
{
    self = [super initWithFrame:CGRectMake(0, 0, 40, 40)];
    if (self) {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        self.v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
        self.v2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
        self.v3 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];

        [self addSubview:self.v1];
        [self addSubview:self.v2];
        [self addSubview:self.v3];
        NSDictionary *views = @{@"v1" : self.v1, @"v2" : self.v2, @"v3" : self.v3};
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[v1]-10-[v2]-10-[v3]-10-|" options:0 metrics:@{@"10":@10} views:views]];
        [self layoutIfNeeded];
    }
}

但我收到了冲突的约束消息:

(
    "<NSLayoutConstraint:0xed9f040 H:|-(10)-[UIView:0xed9ad30]   (Names: '|':MyView:0xed9a040 )>",
    "<NSLayoutConstraint:0xed9f270 H:[UIView:0xed9ad30]-(10)-[UIView:0xed9c370]>",
    "<NSAutoresizingMaskLayoutConstraint:0xeda3770 h=&&& v=-&- UIView:0xed9c370.midX == 0.5*MyView:0xed9a040.width>",
    "<NSAutoresizingMaskLayoutConstraint:0xeda37a0 h=&&& v=-&- UIView:0xed9c370.width == MyView:0xed9a040.width>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xed9f270 H:[UIView:0xed9ad30]-(10)-[UIView:0xed9c370]>

我的猜测是它与无法调整大小的超级视图有关。但我总体上对此有些困惑。有谁知道我做错了什么?

4

1 回答 1

3

您要确保您以编程方式创建的视图设置translatesAutoresizingMaskIntoConstraintsNO,例如:

self.v1.translatesAutoresizingMaskIntoConstraints = NO;
self.v2.translatesAutoresizingMaskIntoConstraints = NO;
self.v3.translatesAutoresizingMaskIntoConstraints = NO;

如果您希望这三个子视图彼此宽度相同,间隔 10,您可以使用水平 VFL:

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[v1]-10-[v2(==v1)]-10-[v3(==v1)]-10-|" options:0 metrics:nil views:views]];

显然,每个子视图之间的间距为 10 点,父视图必须宽于 40 点宽。例如,如果父视图是 100 点宽,一旦您将子视图之间的 10 个点空间考虑在内(为子视图本身留出 60 个点的宽度),约束系统将使每个子视图宽 20 点。

而且,如果您希望它们的高度为 40 点,您可以定义垂直约束(以及定义您希望它们距其父视图顶部多远):

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v1(40)]" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v2(40)]" options:0 metrics:nil views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v3(40)]" options:0 metrics:nil views:views]];

这将它们定义为与父视图的偏移为零,但高度为 40 点。

而且,如果您已经根据约束定义了视图,则不需要使用initWithFrame,而只需使用init. 使用自动布局时,您通常不指定frame任何内容,而是让约束决定大小。

于 2013-09-17T20:17:34.113 回答