自动布局 - 复杂约束

时间:2014-09-24 14:37:24

标签: ios objective-c autolayout

我试图以编程方式使用自动布局在表格单元格中显示内容。我希望内容显示如下:

[标题]
[图片] [日期]
[长文本字符串,跨越表格的宽度,最多两行]

我的代码如下所示:

-(NSArray *)constraints {
    NSMutableArray * constraints = [[NSMutableArray alloc]init];
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_titleLabel, _descriptionLabel, _dateLabel, _ratingBubbleView);

    NSDictionary *metrics = @{@"padding":@(kPadding)};

    NSString *const kVertical = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_ratingBubbleView]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|";
    NSString *const kVertical2 = @"V:|-(>=0,<=padding)-[_titleLabel]-(<=padding)-[_dateLabel]-(<=padding)-[_descriptionLabel]-(>=0,<=padding)-|";
    NSString *const kHorizontalDescriptionLabel = @"H:|-padding-[_descriptionLabel]-padding-|";
    NSString *const kHorizontalTitleLabel = @"H:|-padding-[_titleLabel]";
    NSString *const kHorizontalDateLabel = @"H:|-padding-[_ratingBubbleView]-padding-[_dateLabel]";

    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical options:0 metrics:metrics views:viewsDictionary]];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kVertical2 options:0 metrics:metrics views:viewsDictionary]];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDescriptionLabel options:0 metrics:metrics views:viewsDictionary]];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalTitleLabel options:0 metrics:metrics views:viewsDictionary]];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:kHorizontalDateLabel options:0 metrics:metrics views:viewsDictionary]];

    return constraints;
}

这是结果: This is the result

1 个答案:

答案 0 :(得分:1)

好的,我不会尝试修复你的代码。我将创建用于实现布局的约束。我会将思考过程放在评论中。

首先获得一个漂亮的垂直布局......

// I'm just using standard padding to make it easier to read.
// Also, I'd avoid the variable padding stuff. Just set it to a fixed value.
// i.e. ==padding not (>=0, <=padding). That's confusing to read and ambiguous.
@"V:|-[titleLabel]-[ratingBubbleView]-[descriptionLabel]-|"

然后逐层添加水平约束...

// constraint the trailing edge too. You never know if you'll get a stupidly
// long title. You want to stop it colliding with the end of the screen.
// use >= here. The label will try to take it's intrinsic content size
// i.e. the smallest size to fit the text. Until it can't and then it will
// break it's content size to keep your >= constraint.
@"|-[titleLabel]->=20-|"

// when adding this you need the option "NSLayoutFormatAlignAllBottom".
@"|-[ratingBubbleView]-[dateLabel]->=20-|"

@"|-[descriptionLabel]-|"

尽量不要“过度约束”你的观点。在您的代码中,您使用多个约束限制相同的视图(例如,将descriptionLabel添加到超级视图的底部)。

一旦定义了它们,就不需要再次定义它们。

再次,填充。只需使用padding而不是>=padding。 &gt; = 20表示20,21.5还是320?布局时,不平等是模棱两可的。

此外,在我的约束中,我使用布局选项将日期标签的垂直轴约束到评级视图。即“与评级视图垂直保持一致”。而不是限制标题标签和东西......这意味着我只需要定义一行UI的位置一次。