rwakelan
rwakelan

Reputation: 193

UITableViewCell doesn't display text

I have a small app that lists a bunch of items in a database. If you click one of the items, the app switches to a new view that shows you all of the information on that particular item. Since the amount of information shown is dynamic, I do this by making the second view a UITableView and setting up the size of each row as needed for the particular object being shown. This normally works fine, but one of the items has a wall of text for the last item shown. When I try to view the information on this particular object, it doesn't display anything where the wall of text should be.

While dubugging I can tell the text that is being used to determine the size the cell and label need to be is correct. It seems like it is determining a size correctly (it gives me a height of 21298 for the cell and 21294 for the label) and I can scroll down into what appears to be a rather large empty label. However, the display is a bit messed up, almost as if the screen was refreshing. The text at the top of the view stutters from where it started all the way to the top of the screen and the scroll bar on the right side doesn't repaint correctly either.

Anyone seen something like this before?

Sorry, can't post the screenshots I have since I don't have enough rep

EDIT: Figured out an answer. I will post it as an answer once the minimum time passes.

I figured out a workaround, if anyone else runs into this.

After some digging around, I found out that when the source string length gets to around 41,000, it starts causing this drawing error. So I split up any string over ~30,000 and added multiple rows to the table. It now displays the entire wall of text.

Code:

#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 2.0f

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
  //static NSString *CellIdentifier = @"Cell";
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d", [indexPath row]];
UILabel *label = nil;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

    label = [[UILabel alloc] initWithFrame:CGRectZero];
    [label setLineBreakMode:UILineBreakModeWordWrap];
    [label setMinimumFontSize:10.0];
    [label setNumberOfLines:0];
    [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
    [label setTag:1];

    if ([indexPath row] == 1 || [indexPath row] == 2)
    {
        [label setTextColor:[UIColor redColor]];
    }
    else if ([indexPath row] == 3)
    {
        [label setTextColor:[UIColor colorWithRed:0.0f green:150.f/255.f blue:30.f/255.f alpha:1.0f]];
    }
    else if ([indexPath row] == 5)
    {
        [label setTextColor:[UIColor colorWithRed:155.f/255.f green:145.f/255.f blue:0.0f alpha:1.0f]];
    }

    [[cell contentView] addSubview:label];
}

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

CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

if (!label)
{
    label = (UILabel *)[cell.contentView viewWithTag:1];
}

[label setText:text];
[label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), MAX(size.height, 30.0f))];

// Configure the cell...

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [cardInfo objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN *2), 20000000000000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 30.0f);
return height + (CELL_CONTENT_MARGIN * 2);
}

Upvotes: 0

Views: 426

Answers (2)

rwakelan
rwakelan

Reputation: 193

I figured out a workaround, if anyone else runs into this.

After some digging around, I found out that when the source string length gets to around 41,000, it starts causing this drawing error. So I split up any string over ~30,000 and added multiple rows to the table. It now displays the entire wall of text.

Upvotes: 0

rob mayoff
rob mayoff

Reputation: 385540

This is an error:

[label setTag:[indexPath row]];

When you are constructing the cell's view hierarchy, you should never refer to the row number. Why? Because a cell can be reused for a different row! That's what dequeueReusableCellWithIdentifier: is all about.

Instead, define a constant for your label's tag:

static const int LabelTag = 100;

Use that constant to set the tag:

label.tag = LabelTag;

and later when you need to fetch the label to set its text, use the constant again:

label = (UILabel *)[cell.contentView viewWithTag:LabelTag];

Upvotes: 2

Related Questions