1

期待どおりにレンダリングされないグループ化された UITableView があります。追加したラベルの数に基づいて行の高さを指定するために、プログラムで 2 ~ 5 個の UILabels を各 UITableViewCell[cell.contentView addSubview:...]に追加しています。tableView:heightForRowAtIndexPath私は、stackoverflow に関する多数の関連記事を読み、A Closer Look at Table-View Cellsを読みましたが、解決策がクリックされません。この時点での私の唯一の考えは、セルのバリエーションごとにペン先を作成することです (3 行の行 #1、4 行の行 #1、5 行の行 #1) など... しかし、それは少し抜本的なようです.

問題のスクリーンショット:

問題

UITableViewController を拡張する 1 つのテーブル ビュー コントローラーを含むテスト プロジェクトを作成しました。IBOutlet が設定されます。.m の内容は次のとおりです。

- (id)initWithStyle:(UITableViewStyle)style
{
    return [super initWithStyle:UITableViewStyleGrouped];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1; // Hardcoding for example
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 4; // Hardcoding for example
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Detail Cell";
    // Table view will have between 1 and 4 rows and all cells are different... don't think dequeue is needed in this scenario
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];

    NSArray *labels = [self makeLabelsForRows];
    // Add labels for this row
    for (UILabel *label in [labels objectAtIndex:indexPath.row]) {
        [cell.contentView addSubview:label];
    }

    // changing the cell.frame here doesn't seem to help.
    // Removed per Ricard Pérez del Campo's comment
    // CGFloat theHeight = [self tableView:self.tableView heightForRowAtIndexPath:indexPath];
    // cell.frame = CGRectMake(0, 0, 320, theHeight);
    NSLog(@"Cell = %@", cell);
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Normally these are calculated based on cell content. Hardcoding for example
    if (indexPath.row == 0) return 123.0;
    else if (indexPath.row == 1) return 73.0;
    else if (indexPath.row == 2) return 62.0;
    else if (indexPath.row == 3) return 62.0;
    return 44.0;
}


- (NSArray *)makeLabelsForRows
{
    // Array of arrays containing UILables
    NSArray *retVal = [NSArray array];
    // Stores the height of the row
    double y = 0.0f;

    // Showing all rows and labels for example

    // ROW #1
    NSArray *row1 = [NSArray array];
        UILabel *eventTitleLabel, *calendarTitleLabel, *locationLabel, *dateLabel, *timeLabel;

    eventTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    eventTitleLabel.tag = 2;
    eventTitleLabel.font = [UIFont boldSystemFontOfSize:17.0];
    eventTitleLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    eventTitleLabel.text = @"Event Title";
    eventTitleLabel.backgroundColor = [UIColor clearColor];
    row1 = [row1 arrayByAddingObject:eventTitleLabel];
    y += 21.0f;


    locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    locationLabel.tag = 3;
    locationLabel.font = [UIFont systemFontOfSize:15.0];
    locationLabel.textColor = [UIColor darkGrayColor];
    locationLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    locationLabel.backgroundColor = [UIColor clearColor];
    locationLabel.text = @"Event Location";
    row1 = [row1 arrayByAddingObject:locationLabel];
    y += 19.0f;

    calendarTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    calendarTitleLabel.tag = 4;
    calendarTitleLabel.font = [UIFont systemFontOfSize:15.0];
    calendarTitleLabel.textColor = [UIColor redColor];
    calendarTitleLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    calendarTitleLabel.backgroundColor = [UIColor clearColor];
    calendarTitleLabel.text = @"Calendar Title";
    row1 = [row1 arrayByAddingObject:calendarTitleLabel];
    y += 19.0f;

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateStyle:NSDateFormatterFullStyle];
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];

    dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    dateLabel.tag = 5;
    dateLabel.font = [UIFont boldSystemFontOfSize:12.0];
    dateLabel.textColor = [UIColor blueColor];
    dateLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    dateLabel.backgroundColor = [UIColor clearColor];
    dateLabel.text = [dateFormatter stringFromDate:[NSDate date]];
    row1 = [row1 arrayByAddingObject:dateLabel];
    y += 16.0f;

    [dateFormatter setDateStyle:NSDateFormatterNoStyle];
    [dateFormatter setTimeStyle:NSDateFormatterShortStyle];

    timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    timeLabel.tag = 6;
    timeLabel.font = [UIFont boldSystemFontOfSize:12.0];
    timeLabel.textColor = [UIColor blueColor];
    timeLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    timeLabel.backgroundColor = [UIColor clearColor];
    timeLabel.text = [dateFormatter stringFromDate:[NSDate date]];
    row1 = [row1 arrayByAddingObject:timeLabel];
    y += 16.0f;

    retVal = [retVal arrayByAddingObject:row1];



    // ROW #2
    y = 0.0f;

    NSArray *row2 = [NSArray array];
    UILabel *rowTitleLabel, *alert1Label, *alert2Label;

    rowTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    rowTitleLabel.tag = 2;
    rowTitleLabel.font = [UIFont boldSystemFontOfSize:15.0];
    rowTitleLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    rowTitleLabel.text = @"Alert";
    rowTitleLabel.backgroundColor = [UIColor clearColor];
    row2 = [row2 arrayByAddingObject:rowTitleLabel];
    y += 21.0f;

    alert1Label = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    alert1Label.tag = 6;
    alert1Label.font = [UIFont boldSystemFontOfSize:12.0];
    alert1Label.textColor = [UIColor blueColor];
    alert1Label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    alert1Label.backgroundColor = [UIColor clearColor];
    alert1Label.text = @"Alert #1 5 min";
    row2 = [row2 arrayByAddingObject:alert1Label];
    y += 16.0f;

    alert2Label = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    alert2Label.tag = 6;
    alert2Label.font = [UIFont boldSystemFontOfSize:12.0];
    alert2Label.textColor = [UIColor blueColor];
    alert2Label.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    alert2Label.backgroundColor = [UIColor clearColor];
    alert2Label.text = @"Alert #2 15 min";
    row2 = [row2 arrayByAddingObject:alert2Label];
    y += 16.0f;

    retVal = [retVal arrayByAddingObject:row2];


    // ROW #3
    y = 0.0f;

    NSArray *row3 = [NSArray array];
    UILabel *rowTitleLabel2, *urlLabel;

    rowTitleLabel2 = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    rowTitleLabel2.tag = 2;
    rowTitleLabel2.font = [UIFont boldSystemFontOfSize:15.0];
    rowTitleLabel2.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    rowTitleLabel2.text = @"URL";
    rowTitleLabel2.backgroundColor = [UIColor clearColor];
    row3 = [row3 arrayByAddingObject:rowTitleLabel2];
    y += 21.0f;

    urlLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    urlLabel.tag = 6;
    urlLabel.font = [UIFont boldSystemFontOfSize:12.0];
    urlLabel.textColor = [UIColor blueColor];
    urlLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    urlLabel.backgroundColor = [UIColor clearColor];
    urlLabel.text = @"www.here.com";
    row3 = [row3 arrayByAddingObject:urlLabel];
    y += 21.0f;

    retVal = [retVal arrayByAddingObject:row3];

    // ROW #4
    y = 0.0f;

    NSArray *row4 = [NSArray array];
    UILabel *rowTitleLabel3, *notesLabel;

    rowTitleLabel3 = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    rowTitleLabel3.tag = 2;
    rowTitleLabel3.font = [UIFont boldSystemFontOfSize:15.0];
    rowTitleLabel3.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    rowTitleLabel3.text = @"Notes";
    rowTitleLabel3.backgroundColor = [UIColor clearColor];
    row4 = [row4 arrayByAddingObject:rowTitleLabel3];
    y += 21.0f;

    notesLabel = [[UILabel alloc] initWithFrame:CGRectMake(30.0, y, 280.0, 21.0)];
    notesLabel.tag = 6;
    notesLabel.font = [UIFont boldSystemFontOfSize:12.0];
    notesLabel.textColor = [UIColor blueColor];
    notesLabel.backgroundColor = [UIColor clearColor];
    notesLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
    notesLabel.text = @"Boom, notes!";
    notesLabel.lineBreakMode = UILineBreakModeWordWrap;
    row4 = [row4 arrayByAddingObject:notesLabel];
    y += 21.0f;

    retVal = [retVal arrayByAddingObject:row4];

    return retVal;
}

リクエストごとのすべてのサブビューのダンプ:

2012-07-26 14:04:14.333 TestLabels[72259:f803] cell.contentView subviews for row #0 = (
"<UILabel: 0x6da3590; frame = (30 0; 280 21); text = 'Event Title'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x6da3630>>",
"<UILabel: 0x6da3c90; frame = (30 21; 280 21); text = 'Event Location'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x6da3d80>>",
"<UILabel: 0x6da3e00; frame = (30 40; 280 21); text = 'Calendar Title'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 4; layer = <CALayer: 0x6da3dd0>>",
"<UILabel: 0x6885b20; frame = (30 59; 280 21); text = 'Thursday, July 26, 2012'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 5; layer = <CALayer: 0x6883950>>",
"<UILabel: 0x6883a50; frame = (30 75; 280 21); text = '2:04 PM'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 6; layer = <CALayer: 0x6885790>>"
)

2012-07-26 14:04:14.337 TestLabels[72259:f803] cell.contentView subviews for row #1 = (
"<UILabel: 0x6da8730; frame = (30 0; 280 21); text = 'Alert'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x6da6ad0>>",
"<UILabel: 0x6da6c10; frame = (30 21; 280 21); text = 'Alert #1 5 min'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 6; layer = <CALayer: 0x6da70b0>>",
"<UILabel: 0x6da7220; frame = (30 37; 280 21); text = 'Alert #2 15 min'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 6; layer = <CALayer: 0x6da70e0>>"
)

2012-07-26 14:04:14.340 TestLabels[72259:f803] cell.contentView subviews for row #2 = (
"<UILabel: 0xbe71950; frame = (30 0; 280 21); text = 'URL'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0xbe71a90>>",
"<UILabel: 0xbe719c0; frame = (30 21; 280 21); text = 'www.here.com'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 6; layer = <CALayer: 0xbe71d00>>"
)

2012-07-26 14:04:14.342 TestLabels[72259:f803] cell.contentView subviews for row #3 = (
"<UILabel: 0x6a71750; frame = (30 0; 280 21); text = 'Notes'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x6a718e0>>",
"<UILabel: 0x6a717c0; frame = (30 21; 280 21); text = 'Boom, notes!'; clipsToBounds = YES; autoresize = LM+H; userInteractionEnabled = NO; tag = 6; layer = <CALayer: 0x6a716e0>>"
)
4

3 に答える 3

1

投稿した高さのログに基づいて、行 1 の高さを減らし (123.0 の代わりに 96.0 または 100.0 を試してください)、ラベルの自動サイズ変更マスクが正しく設定されていることを確認してください。

あなたのラベルには、flexibletopMargin の autoresizingMask があると思います。これで、ラベルが cell.contentView の下部に貼り付けられます。これが役立つかどうか教えてください。

于 2012-07-26T19:31:19.560 に答える
0

UITableViewが呼び出すメソッド(クラス内にある場合)があり、各行の高さを指定する必要があります。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat cellHeight = 44; // default height
    for (int i = 0; i < [labels count]; i++) {
        cellHeight += 44; // or whatever the size of each of the labels you need
    }
    return cellHeight;
}

これは、各ラベルのセルの高さに44ピクセルを追加する基本的なループです。より多くのカスタム描画などを行う場合は、セルを描画する必要がある高さを計算するために、さらに多くの計算を行う必要がある場合があります。

また、この方法は少し高価です。上記のコードは非常に高価ですが、折り返すテキストやグラフィックのレイアウトなどに基づいて高さを計算する必要がある場合、古いデバイスではスクロールフレームレートが少し損なわれます。

于 2012-07-26T18:54:20.530 に答える
0

テーブル ビューでは、セルのフレームを手動で管理する必要はありません。その高さを設定する責任があるのは、テーブル ビュー デリゲートです。だからあなたの

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

セル フレームを設定しないでください。

于 2012-07-26T18:42:08.153 に答える