0

の中に表示するアイテムの配列がありますUITableViewCell。これらの各アイテムは、 を使用して動的に表示されますUILabel。ビューのレイアウトをセットアップするために autolayout を使用します。

これが私のレイアウト方法ですtableViewCell

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

明確にするために

  • otherView: 中に 2 つUILabel入っています。高さ固定。
  • itemView:内部のitemLabel&の数が不明です。priceLabelの数に基づいて高さを変更しitemsます。
  • itemLabelビューの各制約は、 &を除いてストーリーボードを使用して設定されますpriceLabel

私の中で、私は&を使用して制約をcellForRowAtIndexPath設定しますitemLabelpriceLabelconstraintsWithVisualFormat:

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作成された とpriceLabelが上から下にうまく整列するのではなく、互いに重なり合っていることです。

結果:

最終結果

デバッグを表示:

デバッグを表示

itemLabel&priceLabelが上から下にうまく整列itemViewし、その中のアイテムの数に基づいてサイズが変更されるように、制約を適切に設定するにはどうすればよいですか?

4

1 に答える 1

1

制約が不十分です。itemLabel問題は、たとえば、 oneと の の間に制約を設定していないことですitemLabel。ループするときは、前のアイテム ラベルを追跡して、このアイテム ラベルからスペースを空けることができるようにする必要があります。

別の言い方をすれば、あなたが探しているテクニックは、次の 3 つのケースがあるということです。

  • 最初のラベル。その上にあるもの (おそらくスーパービューの上部) に固定されます。

  • 最後のラベルを除く他のすべてのアイテム ラベル。それぞれが前のラベルに固定されています。

  • 最後のラベル。前のラベルと下に固定されているため、セルに高さが与えられます。

偶然にも、私は実際にこの原理を示すコードを手元に持っています。状況は明らかにあなたの状況と 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 に答える