Reputation:
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:
After hidden textfield and then started editing again:
- (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
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
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