简体   繁体   中英

First and last UITableViewCell keep changing while scrolling

I have a tableView with cells containing one UITextField as a subview for each cell. My problem is that when I scroll down, the text in the first cell is duplicated in the last cell. I can't for the life if me figure out why. I have tried loading the cells from different nibs, having the textFields as ivars. The UITextFields don't seem to be the problem, I'm thinking it has something to do with the tableView reusing the cells.

The textFields all have a data source that keeps track of the text within the textField and the text is reset each time the cell is shown.

Any ideas? I'd really appreciate some more answers for this question.

UPDATE 2: This is the code I have for a custom cell, called JournalCell. Really appreciate the feedback.

I have 8 sections with 1 row each. The first 7 have a textField in them, the last is a cell acting like a button.

I'm testing for the button cell, if it matches the section (7), then it returns that cell, if not, it continues to the rest. Could this be it?

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

NSLog(@"Section %i, Row %i", indexPath.section, indexPath.row);


if (indexPath.section == 7) {

    static NSString *ButtonCellIdentifier = @"ButtonCellIdentifier";

    UITableViewCell *buttonCell = [self.tableView dequeueReusableCellWithIdentifier:ButtonCellIdentifier];

    if (buttonCell == nil) {
        buttonCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ButtonCellIdentifier] autorelease];
        buttonCell.selectionStyle = UITableViewCellSelectionStyleBlue;
        buttonCell.accessoryType = UITableViewCellAccessoryNone;
        buttonCell.textLabel.text = sClearAll;
        buttonCell.textLabel.textAlignment = UITextAlignmentCenter;
        buttonCell.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.8];
        buttonCell.textLabel.backgroundColor = [UIColor clearColor];
    }

    return buttonCell;
}

static NSString *TextCellIdentifier = @"JournalCellIdentifier";

JournalCell *cell = (JournalCell *)[self.tableView dequeueReusableCellWithIdentifier:TextCellIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"JournalCell" owner:self options:nil];
    cell = customCell;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.accessoryType = UITableViewCellAccessoryNone;

    cell.textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
    cell.textField.returnKeyType = UIReturnKeyNext;
    cell.textField.clearButtonMode = UITextFieldViewModeWhileEditing;
} 

switch (indexPath.section) {
    case 0:
        switch (indexPath.row) {
            case 0:
                cell.textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
                self.authorTextField = cell.textField;
                self.authorTextField.text = [self.textFieldDictionary objectForKey:@"author"];
                NSLog(@"Reading Author:%@", [self.textFieldDictionary objectForKey:@"author"]);
                break;
        }
        break;

    case 1:
        switch (indexPath.row) {
            case 0:
                self.yearTextField = cell.textField;
                self.yearTextField.text = [self.textFieldDictionary objectForKey:@"year"];
                NSLog(@"Reading Year:%@", [self.textFieldDictionary objectForKey:@"year"]);
                break;                  
        }
        break;

    case 2:
        switch (indexPath.row) {
            case 0:
                self.volumeTextField = cell.textField;
                self.volumeTextField.text = [self.textFieldDictionary objectForKey:@"volume"];
                NSLog(@"Reading Volume:%@", [self.textFieldDictionary objectForKey:@"volume"]);
                break;                      
        }
        break;

    case 3:
        switch (indexPath.row) {
            case 0:
                self.articleTextField = cell.textField;
                self.articleTextField.text = [self.textFieldDictionary objectForKey:@"article"];
                NSLog(@"Reading Article:%@", [self.textFieldDictionary objectForKey:@"article"]);
                break;          
        }
        break;

    default:
        break;
}

return cell;

}

As you guessed, the issue is most likely coming from the conventional reuse of cells in a UITableView. Create an NSMutableDictionary as a property of your class, and whenever a UITextField is finished editing, set the value of it to a key in your dictionary.

Then, in your cellForRowAtIndexPath method, load the value of the corresponding key in the dictionary.

It would be most ideal to name each key in your dictionary with the format [indexPath section], [indexPath row] , as this will aid in the setting and getting of values.

Hope this helps.

Canada Dev's answer will probably solve your issue, but it's only really a stop-gap rather than a long-term repair.

You should avoid adding subviews in the cellForRowAtIndexPath: method.

You should instead create a custom UITableViewCell (typically by subclassing UITableViewCell) and using that - otherwise you're adding/removing subviews from cells whenever they are dequeued.

If you're not sure what dequeuing of cells actually means, you should probably read up Apple's TableView documentation. Basically, use a UITableViewCell subclass, and you'll be in a much better position than trying to add all your views in your cellForRow method.

Do you really need to save each cell and textField to your viewController and then generate the cell out of this by inserting parts from other cell?

maybe you can save the whole cell in a property (eg self.authorCell ) and then simply display this cell:

if (indexPath.section == 0) {
    return self.authorCell; // or cell = self.authorCell
}

and you can still access the textField by accessing the cell property:

self.authorCell.myTextField

// EDIT: see the Apple documentation for "The Technique for Static Row Content"

Try inserting this right after allocing the cell and before doing any drawing/labeling/etc.

cell.clearsContextBeforeDrawing = YES;

cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;

for (UIView *view in cell.contentView.subviews) {
    [view removeFromSuperview];
}

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