Search code examples
iosxmltableviewcellsubview

iOS how to add UIView to tableview cell effectively


I have a table going where each cell has a UIView in it that is fed from an XMLParser feed. If I leave it how it is, each time I refresh the views build upon each other because they are not getting released/removed, which makes total sense. How would I go about writing my code to avoid that problem, and not having to rebuild the view's each time I refresh. I am stuck in the logic of it and also the actual syntax. Thanks.

Code:

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

  static NSString *CellIdentifier = @"Cell";
  JointCAD *currentCall = [[xmlParser calls] objectAtIndex:indexPath.row];
  self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"texture.png"]];

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

    UIView *selectionView = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 200, 65)];
    [selectionView setBackgroundColor: [UIColor clearColor]];
    cell.selectedBackgroundView = selectionView;
  }

  // Display content in each cell

  cellSeparator = [[UIView alloc] initWithFrame:CGRectMake(10, 7, 300, 65)];
  [cellSeparator setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin |
   UIViewAutoresizingFlexibleRightMargin |
   UIViewAutoresizingFlexibleWidth];
  [cellSeparator setContentMode:UIViewContentModeTopLeft];
  [cellSeparator setBackgroundColor: [UIColor colorWithRed:240.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0]];
  cellSeparator.layer.borderWidth = 1.0;
  cellSeparator.layer.borderColor = [UIColor blackColor].CGColor;
  [cell addSubview:cellSeparator];

  callTypeLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 2, 190, 21)];
  callTypeLabel.text =  [currentCall currentCallType];
  callTypeLabel.backgroundColor = [UIColor clearColor];
  callTypeLabel.font = [UIFont boldSystemFontOfSize:12.0];
  [cellSeparator addSubview:callTypeLabel];

  locationLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 17 , 190, 15)];
  locationLabel.text = [currentCall location];
  locationLabel.backgroundColor = [UIColor clearColor];
  locationLabel.font = [UIFont systemFontOfSize:10.0];
  [cellSeparator addSubview:locationLabel];

  unitsLabel = [[UILabel alloc]initWithFrame:CGRectMake(4, 43, 190, 21)];
  unitsLabel.text = [currentCall units];
  unitsLabel.backgroundColor = [UIColor clearColor];
  unitsLabel.font = [UIFont italicSystemFontOfSize:10.0];
  [cellSeparator addSubview:unitsLabel];

  stationLabel = [[UILabel alloc]initWithFrame:CGRectMake(195 , 25, 75, 20)];
  NSString *station = [@"Station: " stringByAppendingString:currentCall.station];
  stationLabel.text = station;
  stationLabel.backgroundColor = [UIColor clearColor];
  stationLabel.font = [UIFont boldSystemFontOfSize:11.0];
  [cellSeparator addSubview:stationLabel];

  if ([currentCall.county isEqualToString:@"W"]) {
    UIImage  *countyImage = [UIImage imageNamed:@"blue.png"];
    CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
    UIImageView *countyImageLabel = [[UIImageView alloc] initWithFrame:countyImageFrame];
    countyImageLabel.image = countyImage;
    [cellSeparator addSubview:countyImageLabel];
  } else {
    UIImage  *countyImage = [UIImage imageNamed:@"green.png"];
    CGRect countyImageFrame = CGRectMake(275, 10, 18, 18);
    UIImageView *countyImageLabel = [[UIImageView alloc] initWithFrame:countyImageFrame];
    countyImageLabel.image = countyImage;
    [cellSeparator addSubview:countyImageLabel];
  }

  if ([currentCall.callType isEqualToString:@"F"]) {
    UIImage  *callTypeImage = [UIImage imageNamed:@"red.png"];
    CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
    UIImageView *callTypeImageLabel = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    callTypeImageLabel.image = callTypeImage;
    [cellSeparator addSubview:callTypeImageLabel];
  } else {
    UIImage  *callTypeImage = [UIImage imageNamed:@"yellow.png"];
    CGRect callTypeImageFrame = CGRectMake(275, 37, 18, 18);
    UIImageView *callTypeImageLabel = [[UIImageView alloc] initWithFrame:callTypeImageFrame];
    callTypeImageLabel.image = callTypeImage;
    [cellSeparator addSubview:callTypeImageLabel];
  }

  return cell;
}

Solution

  • If I understand your question correctly, I think the solution you want is to subclass UITableViewCell, set up your subviews (UIImageViews and all that) and make them properties on your subclass. Then you can

    if (!cell.imageView) {
        cell.imageView = [[UIImageView alloc] initWithFrame:myFrame];
    }
    

    then just set the image. That way you're sure to not stack image views on top of one another and the correct image will get set when the cell is dequeued.

    EDIT:

    Make a class called MyTableViewCell (or whatever you want to call it but make sure it's a subclass of UITableViewCell) Add @property (strong, nonatomic) UIImageView *imageView;

    Then use MyTableViewCell instead of UITableViewCell in you cellForRowAtIndexPath and you can access the image property of your custom table view cell, check if it exists, if not create it (which is what the above code does) and then set the image. I would give you code but I'm on my phone. Google subclassing UITableviewCell. You should find a ton of examples.