开发者

Problems with UITableViewCell heights with a UILabel and random text lengths

I'm currently trying to get a UITableView to use custom cell heights based on text in an array. The problem I'm seeing is that the text seems to squish together at point rather than filling the full length of a custom cell. This results in the text overlapping over cells, sometimes disappearing under them.

Here's the code I have for determining the cell height, I'm not sure of the standard UILabel text height but this seemed to work well at the height I for the font.

if (indexPath.section == 0) {

    NSString *text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex:[indexPath row]];

    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    CGFloat height = size.height;

    return height + 20;
}

Also just in case the creation of the cells is either a hinderance to my problem or just helps you know what's going on, here's that too.

UITableViewCell *cell;
UITableViewCell *ingredientCell;
UITableViewCell *methodCell;

if (indexPath.section == 0) {
    UILabel *ingredientText;

    static NSString *ingredientCellIdentifier = @"Ingredient Cell";

    ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

    if (ingredientCell == nil)
    {
        ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

        ingredientText = [[UILabel alloc] initWithFrame:CGRectMake(15, 7, 290, 44)];
        [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
        [ingredientText setNumberOfLines:0];
        [ingredientCell.contentView addSubview:ingredientText];

        ingredientText.tag = 1;

        [ingredientText release];

        ingredientCell.contentMode = UIViewContentModeRedraw;
    }

    ingredientText = (UILabel*)[ingredientCell viewWith开发者_如何学编程Tag:1];
    ingredientText.text = [[self.recipeDict objectForKey:@"Ingredients"] objectAtIndex: indexPath.row];
    [ingredientText sizeToFit];

    return ingredientCell;
}

This is my second attempt at solving this issue but it seems to be beyond my current ability so I welcome wisdom gained through experience.

UPDATE -

After further investigation it seems that the UILabel ingredientText being resized is causing the issue.

It starts out as tall as it needs to be for the text shown, however when that label is redrawn with a larger height for another piece of text which requires more lines it's never shrunk down again. It seems that the sizeToFit method is prioritising using the available height rather than taking up the width and shrinking the height.

Right now I've set the width again after the sizeToFit which works around the issue but it leads to odd spacing depending on the height of the label.


A couple of things:

  • You have not set the font for the UILabel, which means you're sizing to an unknown height
  • You need to set your UILabel autoresizing mask, so that it sizes when the cell height changes

Here is working code (tested):

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 0) {

        NSString *text = [_items objectAtIndex:[indexPath row]];

        CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        CGFloat height = size.height;

        return height + 20;
    }

    return tableView.rowHeight;
}

#pragma mark - UITableViewDatasource

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell;
    UITableViewCell *ingredientCell = nil;
    UITableViewCell *methodCell;

    if (indexPath.section == 0) {
        UILabel *ingredientText;

        static NSString *ingredientCellIdentifier = @"Ingredient Cell";

        ingredientCell = [tableView dequeueReusableCellWithIdentifier: ingredientCellIdentifier];

        if (ingredientCell == nil)
        {
            ingredientCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier: ingredientCellIdentifier] autorelease];

            ingredientText = [[UILabel alloc] initWithFrame:ingredientCell.bounds];
            ingredientText.font = [UIFont systemFontOfSize:12.0f];
            ingredientText.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
            [ingredientText setLineBreakMode:UILineBreakModeWordWrap];
            [ingredientText setNumberOfLines:0];
            [ingredientCell.contentView addSubview:ingredientText];

            ingredientText.tag = 1;

            [ingredientText release];

            ingredientCell.contentMode = UIViewContentModeRedraw;
        }

        ingredientText = (UILabel*)[ingredientCell viewWithTag:1];
        ingredientText.text = [_items objectAtIndex: indexPath.row];

        return ingredientCell; 
    }

}
  • Be sure you are always be returning a values for tableView:cellForRowAtIndexPath: and tableView:heightForRowAtIndexPath: methods


The solution to this issue was that the width specified in the constant in the cell height method didn't match the frame for the cell text specified later in the cellForRowAtIndexPath method.

Once these are the same the problem resolves itself.

The different constant size led to inconsistent and inaccurate UILabel heights being reported. This led to incorrect table row heights being set.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜