简体   繁体   中英

Maintaining text in UITextFields in UITableViewCells

My Problem: I have a UITableView section that is used to create a list. Each TableViewCell has UITextField in it. When you begin typing the textfield, a new cell is inserted. All of this functionality works perfectly. However, if the user creates many cells, they go off screen and problems occur. Specifically that the cells on top of the section start to get reused. This results in unwanted text in new cells, and the deletion of text in old ones. How might I fix this?

Images of this problem: (in the second image, as I started typing item 6, item 1 appeared below it)

在此输入图像描述

在此输入图像描述

Code to create UITableViewCells:

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


    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        // Intialize TableView Cell
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryNone;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.backgroundColor = [UIColor whiteColor];


        // Initialize TextField
         // ... code ommitted for brevity

        // Custome intializiation per each kind of TextField
        if (indexPath.section == 0) {
            playerTextField.tag = 0;
            playerTextField.placeholder = @"Title";
        }
        else if (indexPath.section == 1) {

            // Here's where the problem starts *********

            playerTextField.tag = indexPath.row + 1;
            playerTextField.placeholder = @"List Item";
        }

            [cell.contentView addSubview:playerTextField];
    }


    return cell;
}

Code to add/delete cells

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{

    NSInteger section = [self.tableView indexPathForCell:(UITableViewCell *)textField.superview.superview].section;
    NSInteger row = [self.tableView indexPathForCell:(UITableViewCell *)textField.superview.superview].row;

    if (section == 0) {

        _myList.name = textField.text;
    }
    else if (section == 1) {

        // Delete cell that is no longer used
        if ([string isEqualToString:@""]) {
            if (textField.text.length == 1) {
                if (cellCount > 1) {
                cellCount = cellCount - 1;

                [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:row inSection:1]] withRowAnimation:UITableViewRowAnimationAutomatic];

                textField.text = @"";
                }
            }
        }

        // Add a new cell
        if (self.beganEditing) {
            if (![string isEqualToString:@""]) {
            if (row == [self.tableView numberOfRowsInSection:1] - 1) {
                cellCount = cellCount + 1;
                [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:row + 1 inSection:1]] withRowAnimation:UITableViewRowAnimationAutomatic];
                self.beganEditing = NO;
                }
            }
        }
    }    

    return YES;
}

As @Bruno said, you need to watch what you put into the initialization of the cell. A good general rule would be to only put universal rules into the cell == nil conditional. Anything that depends on the position of the cell in the table view needs to go outside this if statement.

In the code above, you have a comment "Custom initialization per each kind of text field." That's a pretty good indicator that this code needs to go outside the if statement.

Secondly, you cannot rely on the table view cells to keep your data for you . If you don't already have one, you need to keep an array of strings that represents each entry in the text fields area. Then when asked for a cell by the table view, you can set each text field's text according to its index path outside the cell == nil conditional .

Check out this answer as well.

Hope this helps!

You bug is on the

if (cell == nil)

part of your code. You're not considering the else , which is the case when the cell is reused. (The cell is reused, that's why it's appearing on the bottom).

You should make sure that you treat the reuse case (in other words, that you configure your cell accordingly when its reused)

I found your problem. But it's a bit hard to say.

Try to think about, when table view is going to present a cell in a row, it will choose a cell in the reuse-queue which has the same type of the one is going to be shown. In other words, table view just knows the type of the reused-cell it choosed and the comment of the cell is recognized by which row is in! So let see your code.

You can know that you only creat one cell with your text when is nil. However, when it is going to be used, the cell with the same type don't know which row he is in and so it don't know what kind of comment it hold and just presented with the its last infromations!!

Here's the solution. Try to save your infos in an array well-organized(Such as: you can back your info by which row its in ), basic on its rows, try to update your cell's comment by which row its in relating to the info-array.

hope it can help:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM