以编程方式定位UILabels在UIView中使用autolayout动态添加

时间:2015-04-27 02:49:40

标签: ios objective-c uiview autolayout visual-format-language

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

以下是我如何布置tableViewCell

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

为清楚起见

  • otherView:里面有UILabelitemView。固定高度。
  • itemLabelpriceLabel&amp; items里面。将根据itemLabel
  • 的数量调整高度
  • 每个视图约束都是使用storyboard设置的,除了priceLabel&amp; cellForRowAtIndexPath

itemLabel内,我设置了priceLabel&amp;使用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]]; }
itemLabel

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

结果:

End results

查看调试

View debug

如何正确设置约束以便priceLabel&amp; itemView会从上到下很好地对齐,{{1}}会根据其中的项目数量调整大小吗?

1 个答案:

答案 0 :(得分:1)

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

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

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

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

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

令人难以置信的巧合,我实际上有一些代码说明了这个原则;这种情况显然与你的情况不完全相同,但原则正是你想要遵循的那种事情:

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}]];