2012-07-26 120 views
1

我有一個分組的UITableView沒有按預期呈現。我使用[cell.contentView addSubview:...]以編程方式向每個UITableViewCell添加2到5個UILabels,並使用tableView:heightForRowAtIndexPath根據添加的標籤數量指定行高。我已閱讀了很多相關的帖子,並已閱讀A Closer Look at Table-View Cells,但解決方案沒有爲我點擊。我唯一的想法就是爲每個單元格變體創建一個筆尖(第1行有3行,第1行有4行,第1行有5行)等等,但這似乎有點激烈。動態高度的UITableViewCell沒有正確顯示

截圖的問題:

Problem

我創建一個表視圖控制器延伸的UITableViewController一個測試項目。 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>>" 
) 
+0

你可以發佈什麼日誌,當你打印出日期標籤的高度和y時,你會看到什麼?我認爲在這個計算中有什麼問題。 – 2012-07-26 18:56:39

+0

@calvinBhai我爲我的子視圖添加了日誌。我硬編碼的所有標籤的高度,以21.0和寬度280.0 – Jon 2012-07-26 19:10:26

+0

降低高度爲第1行,(而不是123.0,儘量96.0或100.0),並確保標籤有自動尺寸口罩設定權 – 2012-07-26 19:37:54

回答

1

根據您發佈的高度日誌,我認爲如果您降低行1的高度(而不是123.0,請嘗試96.0或100.0),並且還要確保標籤具有正確設置的自動調整遮罩。

我認爲你的標籤有一個與flexibletopMargin autoresizingMask。這就讓你的標籤貼在cell.contentView的底部。讓我知道這是否有幫助。

+0

從我的autoresizingMask中刪除UIViewAutoresizingFlexibleHeight似乎解決了這個問題。將執行一些更多的測試,但我希望這是我正在尋找的答案。 – Jon 2012-07-26 19:46:38

+0

要修復我從我的每個標籤中刪除'autoresizingMask',因爲該應用程序當前不支持橫向模式。這篇文章(http://www.techotopia.com/index.php/IOS_4_iPhone_Rotation,_View_Resizing_and_Layout_Handling)幫助我更好地理解了自動更新。 – Jon 2012-07-26 20:07:25

+0

很高興幫助!如果實施錯誤,Autoresizing蒙版可能會很痛苦。一旦你掌握了它,它會讓你的生活變得更容易! – 2012-07-26 21:10:13

0

利用表視圖,您不必手動管理單元的框架。這是表格視圖委託負責設置其高度。所以在你的

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

你不應該設置單元格框架。

+0

好要知道在那裏設置框架是不正確的。我刪除了與'CGFloat theHeight ...'相關的行,但單元格仍然顯示如屏幕截圖所示。 – Jon 2012-07-26 18:48:00

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個像素到單元格的高度。如果你進入更多的自定義繪圖等,你可能需要做更多的計算來確定單元格需要繪製的高度。

另外,這種方法有點貴。上面的代碼真的很貴,但是如果你開始不得不根據包裹的文本,圖形佈局等來計算高度,它會在較老的設備上損壞滾動幀率。

+0

我正在使用'tableView:heightForRowAtIndexPath',你需要在我的代碼文章中向下滾動一下才能看到它。我一直不太擔心表現,因爲最多隻有4行,並且滾動功能被禁用。 – Jon 2012-07-26 19:00:15

+0

啊,對不起,沒有看到額外的代碼。 – runmad 2012-07-27 02:51:47