0

我有一系列项目要显示在我的UITableViewCell. 这些项目中的每一个都将使用 动态显示UILabel。我使用自动布局来设置视图布局。

这是我的布局方式tableViewCell

+------------------------------------------------+
| [cellView]                                     |
| +---------------------------------------------+|
| |[otherView] <- fixed height                  ||
| | +------------------------------------------+||
| | |[UILabel]                                 |||
| | +------------------------------------------+||
| +---------------------------------------------+|
| +---------------------------------------------+|
| |[itemView]                                   ||
| | +---------------------------+ +------------+||
| | |[itemLabel]                |-|[priceLabel]|||
| | +---------------------------+ +------------+||
| | +---------------------------+ +------------+||
| | |[itemLabel]                |-|[priceLabel]|||
| | +---------------------------+ +------------+||                                            
| |                                             ||
| |     --Add the next UILabels dynamically--   ||
| +---------------------------------------------+|
+------------------------------------------------+   

为了清楚起见

  • otherView:UILabel里面有2个。固定高度。
  • itemView: 里面有未知数量的itemLabel& priceLabel。将根据items.
  • 除了itemLabel&之外,每个视图约束都是使用故事板设置的priceLabel

在我的内部cellForRowAtIndexPath,我使用itemLabel&设置priceLabel约束constraintsWithVisualFormat:

for (NSDictionary *item in items) {
    UILabel *itemLabel = [[UILabel alloc] init];
    itemLabel.translatesAutoresizingMaskIntoConstraints = NO;
    itemLabel.font = [UIFont systemFontOfSize:14.0f];
    itemLabel.backgroundColor = [UIColor yellowColor];
    itemLabel.text = [item valueForKey:@"item_name"];
    [cell.itemView addSubview:itemLabel];
    
    UILabel *priceLabel = [[UILabel alloc] init];
    priceLabel.translatesAutoresizingMaskIntoConstraints = NO;
    priceLabel.font = [UIFont systemFontOfSize:14.0f];
    priceLabel.textAlignment = NSTextAlignmentRight;
    priceLabel.backgroundColor = [UIColor greenColor];
    priceLabel.text = [NSString stringWithFormat:@"RM %@", [item valueForKey:@"price"]];
    [cell.itemView addSubview:priceLabel];
    
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(cell.itemView, itemLabel, priceLabel);
    [cell.itemView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[itemLabel]-5-[priceLabel(70)]|"
                                                                         options:0
                                                                         metrics:nil
                                                                           views:viewsDictionary]];
    [cell.itemView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[itemLabel]|"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:viewsDictionary]];
    [cell.itemView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[priceLabel]|"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:viewsDictionary]];


}

最终结果如下。唯一的问题是itemLabelpriceLabelcreated 彼此重叠,而不是从上到下很好地对齐。

结果:

最终结果

查看调试:

查看调试

如何正确设置约束,以便itemLabel&priceLabel从上到下很好地对齐,并且itemView将根据其中的项目数调整大小?

4

1 回答 1

1

你没有足够的约束。问题是您没有在 oneitemLabelprevious itemLabel之间设置约束。循环时,您需要跟踪前一个项目标签,以便可以将其与它隔开。

换句话说:您正在寻找的技术是三种情况:

  • 一个标签。它被固定在它上面的任何东西上(可能是超级视图的顶部)。

  • 除最后一个之外的所有其他项目标签。每个都固定到前一个标签。

  • 最后一个标签。它被固定到前一个标签和底部,从而为单元格提供了高度。

一个令人难以置信的巧合,我手头实际上有一些代码可以说明这一原则。情况显然与你的情况不是 100% 相同,但原则正是你想要在这里遵循的那种事情:

UILabel* previousLab = nil;
for (int i=0; i<30; i++) {
    UILabel* lab = [UILabel new];
    // lab.backgroundColor = [UIColor redColor];
    lab.translatesAutoresizingMaskIntoConstraints = NO;
    lab.text = [NSString stringWithFormat:@"This is label %d", i+1];
    [sv addSubview:lab];
    [sv addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[lab]"
                                             options:0 metrics:nil
                                               views:@{@"lab":lab}]];
    if (!previousLab) { // first one, pin to top
        [sv addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[lab]"
                                                 options:0 metrics:nil
                                                   views:@{@"lab":lab}]];
    } else { // all others, pin to previous
        [sv addConstraints:
         [NSLayoutConstraint
          constraintsWithVisualFormat:@"V:[prev]-(10)-[lab]"
          options:0 metrics:nil
          views:@{@"lab":lab, @"prev":previousLab}]];
    }
    previousLab = lab;
}

// last one, pin to bottom, this dictates content size height
[sv addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"V:[lab]-(10)-|"
                                         options:0 metrics:nil
                                           views:@{@"lab":previousLab}]];
于 2015-04-27T03:01:59.913 回答