user1445205
user1445205

Reputation:

Duplicates of text in UITextField when inside UITableView

I have created a UITextField in a UITableView. I type the data in and close the keyboard. However when I scroll down and hide the UITextField and then scroll back up again, the 'UITextField' data is duplicated as seen below:

Original Load of View:

Typed in Data: enter image description here

After hidden textfield and then started editing again:enter image description here

- (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];
}

if ([indexPath section] == 0) { // Email & Password Section
    cell.textLabel.text = @"Subject";
} else {
    cell.textLabel.text = @"Task";
}

cell.selectionStyle = UITableViewCellSelectionStyleNone;

if ([indexPath section] == 0) {
    UITextField *subject = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
    subject.adjustsFontSizeToFitWidth = YES;
    subject.textColor = [UIColor blackColor];
    if ([indexPath row] == 0) {
        subject.placeholder = @"Maths";
        subject.keyboardType = UIKeyboardTypeEmailAddress;
        subject.returnKeyType = UIReturnKeyNext;
    }
    subject.backgroundColor = [UIColor clearColor];
    subject.autocorrectionType = UITextAutocorrectionTypeNo;
    subject.autocapitalizationType = UITextAutocapitalizationTypeWords;
    subject.tag = 0;
    subject.clearButtonMode = UITextFieldViewModeNever;
    [cell.contentView addSubview:subject];
} else {
    UITextView *task = [[UITextView alloc] initWithFrame:CGRectMake(102, 0, 185, 40)];
    task.text = @"fasfashfjasfhasfasdjhasgdgasdhjagshjdgashjdgahjsdghjasgasdashgdgjasd";
    task.editable = NO;
    task.scrollEnabled = NO;
    task.userInteractionEnabled = NO;
    task.textColor = [UIColor colorWithRed: 62.0/255.0 green: 85.0/255.0 blue:132.0/255.0 alpha:1.0];
    task.backgroundColor = [UIColor clearColor];
}



return cell;

}

Upvotes: 1

Views: 1279

Answers (2)

Guillaume Algis
Guillaume Algis

Reputation: 11016

Like Richard said, cells are reused (that's what the identifier purpose is), and that's why you test in your tableView:cellForRowAtIndexPath: for a nil value returned by dequeueReusableCellWithIdentifier:. If a cell already exists (ie. was allocated earlier) and is not displayed anymore, dequeueReusableCellWithIdentifier: will use this cell to display the content of the newly appearing cell.

What you are doing is adding your UITextView every time your cells are displayed and not created. So each time a cell is gets scrolled out of the screen and a new cell pops in, you append a new UITextView in the cell. You should add subviews only in the if (cell == nil) part of your method. As the content of your cells are rather different, I'd recommend using two distinct identifiers.

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

    static NSString *CellIdentifierForSection0 = @"Cell0";
    static NSString *CellIdentifierForSection1 = @"Cell1";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: [indexPath section] == 0 ? CellIdentifierForSection0 : CellIdentifierForSection1];
    if (cell == nil) {

        if ([indexPath section] == 0) { // Email & Password Section

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifierForSection0];
            cell.textLabel.text = @"Subject";

            UITextField *subject = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
            subject.adjustsFontSizeToFitWidth = YES;
            subject.textColor = [UIColor blackColor];
            if ([indexPath row] == 0) {
                subject.placeholder = @"Maths";
                subject.keyboardType = UIKeyboardTypeEmailAddress;
                subject.returnKeyType = UIReturnKeyNext;
            }
            subject.backgroundColor = [UIColor clearColor];
            subject.autocorrectionType = UITextAutocorrectionTypeNo;
            subject.autocapitalizationType = UITextAutocapitalizationTypeWords;
            subject.tag = 0;
            subject.clearButtonMode = UITextFieldViewModeNever;
            [cell.contentView addSubview:subject];
        } else {

            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                       reuseIdentifier:CellIdentifierForSection1];
            cell.textLabel.text = @"Task";

            UITextView *task = [[UITextView alloc] initWithFrame:CGRectMake(102, 0, 185, 40)];
            task.text = @"fasfashfjasfhasfasdjhasgdgasdhjagshjdgashjdgahjsdghjasgasdashgdgjasd";
            task.editable = NO;
            task.scrollEnabled = NO;
            task.userInteractionEnabled = NO;
            task.textColor = [UIColor colorWithRed: 62.0/255.0 green: 85.0/255.0 blue:132.0/255.0 alpha:1.0];
            task.backgroundColor = [UIColor clearColor];
        }

        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }

    return cell;
}

Note that this code is mainly for example purpose, and could be greatly reducted. Moreover, you should use subclass(es) of UITableViewCell like Richard suggested, as it will help organizing your code and make it more reusable.

BUT do NOT use drawRect: to add subviews. This is unnecessary and will impact performances. drawRect: should only be used if you intend to make real drawing like with CoreAnimation or CoreGraphics. Adding subview should be done in initWithFrame: or initWithCoder: depending of your use of Interface Builder or not.

Upvotes: 4

Richard Brown
Richard Brown

Reputation: 11436

Remember cells get reused, therefore the subviews are added each time it's reused. If you're going to add subviews to a cell you're best off creating a subclass of UITableViewCell and adding the subviews in the drawRect: method of that subclass. That way the modifications are part of the cell and aren't added each time the cell is reused.

Upvotes: 0

Related Questions