views:

832

answers:

2

I have found some posts which are similar to my issue but not quite the same.

In my app the user can navigate between several uitableviews to drill down to the desired result. When a user goes forward, then backward, then forward, etc it is noticeable that the rows are being redrawn/re-written and the text gets bolder and bolder.

I have found that in some of the posts this may relate to the way that I am creating the rows, using a uilable within the cellforrowatindexpath method.

Is there something that I need to do so that the rows are not repopulate/redrawn each time a user goes forward and backward between the tableviews? Do I need to add something to the code below or add something to the viewwillappear method (currently there is a 'reloaddata' in the viewwillappear for the table but doesn't seem to help)?

Here is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
{
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

 UILabel *label = [[[UILabel alloc] init] autorelease];
 label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20];
 label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
 label.textColor = [UIColor blackColor];
 label.backgroundColor = [UIColor clearColor];
 label.opaque = NO;
 label.text = [mapareaArray objectAtIndex:indexPath.row];
 [cell.contentView addSubview:label];

 CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
 bgView.borderColor = [UIColor clearColor];
 bgView.fillColor = [UIColor whiteColor];
 bgView.position = CustomCellBackgroundViewPositionSingle;
 cell.backgroundView = bgView;
 return cell;
}
+3  A: 

The problem you are having is due to this line:

[cell.contentView addSubview:label];

You are adding a subview to the table cell whether it's a new cell or not. If it's an old cell (dequeued from the reusable pool), then you will add yet another subview to the cell.

Instead, you should tag the UILabel, and then locate it with the tag to modify the content of that UILabel. Add (and set all of its attributes) and tag the UILabel inside the if( cell == nil ) block:

if(cell == nil) {
  // alloc and init the cell view...

  UILabel *label = [[[UILabel alloc] init] autorelease];
  label.tag = kMyTag; // define kMyTag in your header file using #define
  // and other label customizations
  [cell.contentView addSubview:label]; // addSubview here and only here
  ...
}

Then locate it with:

UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];

And no need to re-add it as a subview outside of the if(cell == nil) block. The subview is already there (and that's why reusing the cell views are so much more efficient, if you do it correctly, that is ;).

Thank you so much for this. Big help.One final question on this - I don't have a programming background so not sure what you mean by use #define in the header file. What is the syntax to do this? I've seen it before and have attempted to put '#define kMyTag' in the header but this doesn't work... I'm assuming that you need to defined kMyTag to a value but not sure what the syntax would be to do this. Can you help?
SKayser
A: 

.h file The 'define' is put after the #import statements at top of header file, and was put as 0 because I don't know how else to define it:

#define kMyTag 0

.m file I have updated this section as per your comments, but a) the table is not populated, b) when the user has navigated to the next view and goes back to this view it fails with a "unrecognized selector sent to instance", and c) I had to put in the two 'return cell;' entries or it falls over. I think I have things in the wrong order and maybe didn't initialise things properly????

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) 
 {
  cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
  cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  cell.selectionStyle = UITableViewCellSelectionStyleNone;

  UILabel *label = [[[UILabel alloc] init] autorelease];
  label.tag = kMyTag; // define kMyTag in your header file using #define
  label.font = [UIFont fontWithName:@"Arial-BoldMT" size:20];
  label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
  label.textColor = [UIColor blackColor];
  label.backgroundColor = [UIColor clearColor];
  label.opaque = NO;

  CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
  bgView.borderColor = [UIColor clearColor];
  bgView.fillColor = [UIColor whiteColor];
  bgView.position = CustomCellBackgroundViewPositionSingle;
  cell.backgroundView = bgView;

  [cell.contentView addSubview:label]; // addSubview here and only here
  return cell;
 }
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];
return cell;
}
SKayser
I am not sure if you should use 0 for the value of kMyTag. Try starting from 1, since 0 may be the default for everything. After that change, remove the return cell inside the if block.
Thanks once again! That works now! Appreciate your time!
SKayser