Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextFields in UITableView, entered values reappearing in other cells

I have a UITableView with about 20 cells, in each cell there are three UITextFields. I did NOT subclass UITableViewCell, but when setting up each cell I set the textfields tag value to a constant plus the row number. So for each row the tag of the textfield is incremented by one.

When I run the app and enter a value in for example row one, it may reappear on row 12. The behavior is not the same each time i run the app.

I should add that I have an array storing the contents entered in each textfield. When a textfield is edited, I save the new value to the array and when the cell is again requested by the tableview i set the textfields value to that stored in the array.

Does this have something to do with reusing UITableViewCells? When reusing a cell, can textfields in different rows get the same tag numbers? Say for example that the first cell (textfield tag=1001) is reused on row 12, then we have two textfields with the same tag number. If I then enter a value on row 1 and later load row 12, the value from cell one will be loaded from the array and put in row 12 also.

If this is happening, how do I fix it? Each cell does not have a reference to the textfield, so I don't think I can edit a textfield's tag value by just having access to the cell which it is in.

EDIT:

Here is the code for UITableView:cellForRowAtIndexPath:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
            //Modify cell, adding textfield with row-unique index value
            cell = [self modifyCellForHoleInfo:cell atIndexPath:indexPath];

    }
    cell.accessoryType = UITableViewCellAccessoryNone; 

    // Load value for textfield stored in dataArray
    ((UITextField *)[cell viewWithTag:1000+indexPath.row]).text = [dataArray objectAtIndex:indexPath.row];

Thanks!

like image 464
Isak T. Avatar asked May 29 '11 19:05

Isak T.


2 Answers

The issue is that when the cell is reused (i.e. dequeueReusableCellWithIdentifier returns non-nil), the cell is returned with the existing UITextView. To maintain the uniqueness of the tags, it'll be better to remove any previous UITextField:

- (void)removeExistingTextSubviews:(UITableViewCell *)cell
{
    NSMutableArray *toRemove = [NSMutableArray array];
    // I don't know if you have non-TextField subviews
    for (id view in [cell subviews]) {
        if ([view isKindOfClass:[UITextField class]] && view.tag >= 1000) {
           [toRemove insert:view];
        }
    }

    for (id view in toRemove) {
        [toRemove removeFromSuperView];
    }
}

...

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
} else {
    [self removeExistingTextSubviews:cell];
}
//Modify cell, adding textfield with row-unique index value
cell = [self modifyCellForHoleInfo:cell atIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone; 

// Load value for textfield stored in dataArray
((UITextField *)[cell viewWithTag:1000+indexPath.row]).text = [dataArray objectAtIndex:indexPath.row];

Please note that I haven't compiled the code, but it should serve as a starting point.

like image 103
notnoop Avatar answered Sep 29 '22 12:09

notnoop


Just get the textfield text into Dictionary setObject by label text and again check by label Text assign the text to corresponding Textfield.. here is my code...

//In Interface
NSMutableDictionary *amounts;
amounts =[[NSMutableDictionary alloc]init];

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

static NSString *CellIdentifier = @"MoneyEntryIdentifier";
static NSString *CellNib = @"MoneyEntry";
MoneyEntryTableViewCell *cell = (MoneyEntryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (!cell)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
cell = (MoneyEntryTableViewCell *)[nib objectAtIndex:0];
}

UILabel     *lblname  = (UILabel *)    [cell lblMemName];
lblname.tag =100;
UITextField *txtfield = (UITextField *)[cell textAmount];
txtfield.tag =indexPath.row;

[txtfield addTarget:self  action:@selector(textFieldDidChange:)    forControlEvents:UIControlEventEditingChanged];
lblname.text = tabledata[indexPath.row];
txtfield.placeholder = [NSString stringWithFormat:@"%ld",(long)indexPath.row];


if ([amounts valueForKey:lblname.text] != nil) {
 txtfield.text = [amounts valueForKey:lblname.text];
} else {
 txtfield.text = @"";
}

cell.selectionStyle =UITableViewCellSelectionStyleNone;
return cell;
}

 -(void)textFieldDidChange:(UITextField *)txtField
 {
 UILabel *label = (UILabel *)[txtField.superview viewWithTag:100];
 NSString *labelString = label.text;
 NSString *textFieldString = txtField.text;
 [amounts setObject:textFieldString forKey:labelString];
 }

Change the nib to your tableview cell...

like image 37
Mohamed Nazir Avatar answered Sep 29 '22 12:09

Mohamed Nazir