2012-07-26 4 views
1

그룹화 된 UITableView가 예상대로 렌더링되지 않습니다. 프로그래밍 방식으로 각 UITableViewCell에 2와 5 UILabels 사이에 [cell.contentView addSubview:...]을 사용하여 추가하고 tableView:heightForRowAtIndexPath을 사용하여 추가 할 레이블의 수를 기반으로 행 높이를 지정합니다. 나는 stackoverflow에 많은 관련 게시물을 읽고 A Closer Look at Table-View Cells 읽었지만 솔루션 나를 위해 클릭하지 않습니다. 이 시점에서 내 생각은 모든 셀 변형 (3 행 1 행, 4 행 5 행, 1 행 1 행) 등을위한 펜촉을 만드는 것입니다.하지만 다소 과감한 것으로 보입니다. 문제동적 높이가 올바르게 표시되지 않는 UITableViewCell

스크린 샷 :

Problem

는 I 한 테이블 뷰 컨트롤러있는 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를 인쇄 할 때 표시되는 로그를 게시 할 수 있습니까? 그 계산에는 뭔가 잘못된 것이 있다고 생각합니다. –

+0

@calvinBhai 내 하위 뷰에 대한 로그를 추가했습니다. 모든 레이블의 높이를 21.0으로, 너비를 280.0으로 하드 코드했습니다. – Jon

+0

행 1 (123.0 대신 96.0 또는 100.0)의 높이를 줄이고 레이블에 자동 크기 조정 마스크가 올바르게 설정되어 있는지 확인하십시오 –

답변

1

게시 한 높이 로그에 따라 행 1의 높이를 줄이면 (123.0 대신 96.0 또는 100.0으로 시도) 라벨에 자동 설정 마스크가 올바르게 설정되어 있는지 확인하십시오.

라벨에 flexibletopMargin이있는 자동 크기 조정 마스크가 있다고 생각합니다. 라벨이 셀의 아래쪽에 붙도록 만듭니다 .contentView. 이것이 도움이되는지 알려주십시오.

+0

내 autoresizingMask에서 UIViewAutoresizingFlexibleHeight를 제거하면 문제가 해결 된 것으로 보입니다. 좀 더 많은 테스트를 수행 할 것이지만 이것이 내가 찾고있는 대답이 될 것으로 기대합니다. – Jon

+0

앱이 현재 가로 모드를 지원하지 않기 때문에 각 레이블에서'autoresizingMask'를 삭제했습니다. 이 [article] (http://www.techotopia.com/index.php/IOS_4_iPhone_Rotation,_View_Resizing_and_Layout_Handling)은 자동 크기 조정에 대한 이해를 도와주었습니다. – Jon

+0

도움이 되니 기쁩니다! 자동 구현 마스크가 잘못 구현되면 고통이 될 수 있습니다. 일단 마스터하면, 인생이 훨씬 쉬워 질 것입니다! –

0

, 수동 셀의 프레임을 관리 할 필요가 없습니다. 높이를 설정하는 것은 테이블 뷰 대리자입니다. 그래서 당신의

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

당신은 셀 프레임을 설정하면 안됩니다.

+0

좋습니다 그곳에 프레임을 설정하는 것이 옳지 않다는 것을 아는 것. 'CGFloat theHeight ... '와 관련된 줄은 제거했지만 스크린 샷과 같이 셀은 여전히 ​​나타납니다. – Jon

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

+0

아, 죄송합니다. 추가 코드를 보지 못했습니다. – runmad

관련 문제