pankaj
pankaj

Reputation: 8328

data of uitableviewcell overlapping with each other on scrolling

I have a tableview with four sections and all of the sections have two textfields and a label in different rows. I have added some text as placeholder of textfield. Initially the data appears fine but when I scroll the tableview the cell starts to have overlapped data.
My Code:

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

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.row==0) {
    UITextField *txtName = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 300, 30)];
    txtName.placeholder = @"Full Name";
    [cell.contentView addSubview:txtName];
    [txtName release];
}
else if(indexPath.row==1) {
    UITextField *txtEmail = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 300, 30)];
    txtEmail.placeholder = @"Email";
    [cell.contentView addSubview:txtEmail];
    [txtEmail release];
}
else if(indexPath.row==2){
    cell.textLabel.text = @"Select Date of Birth";
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Configure the cell...

return cell;

}

thanks in advance
Pankaj

Upvotes: 2

Views: 7638

Answers (2)

Jason Cragun
Jason Cragun

Reputation: 3233

You need to create your text fields only in the block of code that inits the cell. Remember that the table view recycles cells so as you scroll off the screen you get a reused and recycled cell that already has a textfield. You are then creating a new textfield and overlaying the new textfield on the existing one, hence you get overlapping.

here is your code properly refactored

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

        //create the textField here, and we will reuse it and reset its data for each row.
        UITextField *txtField = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 300, 30)];
        [cell.contentView addSubview:txtField];
        txtField.tag=110; //should declare a constant that uniquely defines your textField;
        [txtField release];

    }

    // Configure the cell...

    //ok, now we retrieve the textField and set its data according to the row.
    UITextField *txtField = (UITextField *)[cell.contentView viewWithTag:110];

    if(indexPath.row==0) {
        txtField.placeholder = @"Full Name";   
    }
    else if(indexPath.row==1) {
        txtField.placeholder = @"Email";    
    }
    else if(indexPath.row==2){
        txtField.placeholder = nil;  //? did you mean to set something here?
        cell.textLabel.text = @"Select Date of Birth";
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }


    return cell;
}

Upvotes: 17

Hussain KMR Behestee
Hussain KMR Behestee

Reputation: 852

I have just modified the previous one for missing an else condition which made an bad access error. The modified code is below:

You need to create your text fields before the block of code that inits the cell and init and add this text field in the block of code that inits the cell. Remember that the table view recycles cells so as you scroll off the screen you get a reused and recycled cell that already has a textfield. You are then creating a new textfield and overlaying the new textfield on the existing one, hence you get overlapping.

here is your code properly refactored

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

static NSString *CellIdentifier = @"Cell";
UITextField *txtField;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

//init the textField here, and we will reuse it and reset its data for each row.
txtField = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 300, 30)];
[cell.contentView addSubview:txtField];
txtField.tag=110; //should declare a constant that uniquely defines your textField;
[txtField release];

}
else{

// if the textfield is alread created and now dequed

    //ok, now we retrieve the textField and set its data according to the row.
    txtField = (UITextField *)[cell.contentView viewWithTag:110];
}    


    if(indexPath.row==0) {
        txtField.placeholder = @"Full Name";   
    }
    else if(indexPath.row==1) {
        txtField.placeholder = @"Email";    
    }
    else if(indexPath.row==2){
        txtField.placeholder = nil;  //? did you mean to set something here?
        cell.textLabel.text = @"Select Date of Birth";
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }


    return cell;
    }

Upvotes: 2

Related Questions