Question

I have a UITableView in an iPhone application which I am refreshing (by calling [self.tableView reloadData] in the action method for a UISegmentedControl dynamically embedded in one of the UITableView cells. The table view is refreshed to update a text value for one of the cells.

However, the following code seems to produce an unwanted side-effect. It appears that each time the UITableView refreshes it creates a new instance of the UISegmentedControl (and possibly the images - I'm not sure) over the existing one(s).

The only reason I notice this is that with each refresh a barely perceptible border starts to form around the UISegmentedControl and the application slows noticeably. I would be extremely grateful for any suggestions/code-solutions to my current predicament.

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";


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

    NSUInteger section = indexPath.section;
    NSUInteger row = indexPath.row;

    // Set up the cell...       


    //populates the personal info section
    if (section == kPersonalInfoAddSection) {

        if (row == kNameRow) {

                    //Other code irrelevant to this question was removed for the sake of clarity
        }
        else if(row == kHeightRow) {

            cell.imageView.image = [UIImage imageNamed:@"tableview_height_label.png"];
                    //THIS IS THE TEXT I'M TRYING TO UPDATE
            cell.textLabel.text = [Formatter formatHeightValue:mainUser.heightInMM forZone:self.heightZone];
            cell.detailTextLabel.text = REQUIRED_STRING;

        }
    }

    //populates the units section
    if (section == kUnitsSection) {

        if (row == kHeightUnitsRow) {
            NSArray *heightUnitsSegments = [[NSArray alloc] initWithObjects:FT_AND_IN_STRING, M_AND_CM_STRING, nil];

            UISegmentedControl *heightUnitControl = [[UISegmentedControl alloc] initWithItems:heightUnitsSegments];

            CGRect segmentRect = CGRectMake(90, 7, 200, 30);
            [heightUnitControl setFrame:segmentRect];
            //[heightUnitControl setSelectedSegmentIndex:0];
            [heightUnitControl addTarget:self action:@selector(heightSegmentClicked:) forControlEvents:UIControlEventValueChanged];
            heightUnitControl.tag = kHeightSegmentedControlTag;

            cell.textLabel.text = @"Height:";
            cell.detailTextLabel.text = @"(units)";
            [cell.contentView addSubview:heightUnitControl];

            [heightUnitsSegments release];
            [heightUnitControl release];

        }
        else if(row == kWeightUnitsRow) {

                    //Other code irrelevant to this question was removed for the sake of clarity    

        }
    }

    return cell;
}

Thank you all in advance!

Was it helpful?

Solution

You're right, it is creating a new instance of the UISegmentedControl. It's because you are using a generic cell identifier, @"Cell", then adding the UISegmentedControl each time, never removing it. The cells get cached containing the UISegmentedControl, you retrieve the cached cell and add the control again.

You could use a more specific cell identifier and if cell != nil you know it contains the UISegmentedControl already. Or create a new cell each time that way you're not using a cached cell that already contains the control.

With the image view you just set the cells image view property without adding a new view to the cell so that one is ok, it gets replaced each time.

Since the text you are trying to update doesn't have to do with the UISegmentedControl I think you should be able to use a more specific cell identifier and add the control only on cell creation.

OTHER TIPS

- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray *arr1=[NSArray arrayWithObjects:@"img1.jpg",@"img2.jpg",nil];
    NSArray *arr2=[NSArray arrayWithObjects:@"img1.jpg",@"img2.jpg",@"img3.jpg",@"img4.jpg",@"img5.jpg",@"img6.jpg",nil];
    NSArray *arr3=[NSArray arrayWithObjects:@"img6.jpg",@"img5.jpg",@"img2.jpg",@"img1.jpg",nil];

    Imgs = [[NSArray alloc] initWithArray:[NSArray arrayWithObjects:arr1,arr2,arr3,nil]];


    NSDictionary *dic1=[NSDictionary dictionaryWithObjectsAndKeys:@"Ahmedabad",@"Name",@"Picture 5.png",@"Rating",@"Picture 1.png",@"Photo",arr1,@"img",nil];
    NSDictionary *dic2=[NSDictionary dictionaryWithObjectsAndKeys:@"Rajkot",@"Name",@"Picture 5.png",@"Rating",@"Picture 2.png",@"Photo",nil];
    NSDictionary *dic3=[NSDictionary dictionaryWithObjectsAndKeys:@"Baroda",@"Name",@"Picture 5.png",@"Rating",@"Picture 7.png",@"Photo",nil];

    tblArray=[[NSArray alloc] initWithObjects:dic1,dic2,dic3,nil];
    [myTbl reloadData];

}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.navigationController.navigationBarHidden=NO;
    [self.navigationController.navigationBar setUserInteractionEnabled:YES];

}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.navigationController.navigationBarHidden=YES;
}



-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [tblArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *CellIdentifer=[NSString stringWithFormat:@"%i",indexPath.row];
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifer];
    if(cell==nil){
        cell=[self myCustomCell:CellIdentifer dicToSet:[tblArray objectAtIndex:indexPath.row]];
        [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
    }
    return cell;
}

-(UITableViewCell*)myCustomCell:(NSString*)CellIdentifer dicToSet:(NSDictionary*)dicToSet{
    UITableViewCell *cell=[[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, 320, 44) reuseIdentifier:CellIdentifer] autorelease];

    UIImageView *imgV=[[UIImageView alloc] initWithFrame:CGRectMake(2, 2, 40, 40)];
    [imgV setImage:[UIImage imageNamed:[dicToSet valueForKey:@"Photo"]]];
    [cell addSubview:imgV];
    [imgV release];

    UILabel *lbl=[[UILabel alloc] initWithFrame:CGRectMake(44, 2, 276, 20)];
    [lbl setText:[dicToSet valueForKey:@"Name"]];
    [cell addSubview:lbl];
    [lbl setBackgroundColor:[UIColor clearColor]];
    [lbl setFont:[UIFont fontWithName:@"Helvetica-Bold" size:18]];
    [lbl release];


    UIImageView *imgV1=[[UIImageView alloc] initWithFrame:CGRectMake(44, 24, 70, 20)];
    [imgV1 setImage:[UIImage imageNamed:[dicToSet valueForKey:@"Rating"]]];
    [cell addSubview:imgV1];
    [imgV1 release];


    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    nxtPlcDtl=[[plcFullDtl alloc] initWithNibName:@"plcFullDtl" bundle:nil];
    nxtPlcDtl.dict=[[NSDictionary alloc] initWithDictionary:[tblArray objectAtIndex:indexPath.row]];
    nxtPlcDtl.Imgs = [Imgs objectAtIndex:indexPath.row];
    nxtPlcDtl.comment1 = [comment1 objectAtIndex:indexPath.row];
    nxtPlcDtl.vedio = [vedio objectAtIndex:indexPath.row];

    [self.navigationController pushViewController:nxtPlcDtl animated:YES];



    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top