I have a uiview consisting of a map view on top, and a uitableview below. the table view has cells with uitextFields in them with placeholders.
When I edit the fields the placeholder disappears correctly, but if I scroll the uitableviewcells out of sight (i.e. "behind" the map view that sits above the table view), the placeholders reappear together with the content that was written into the uitextfield.
If I replace the placeholders with normal text, and clear the text on textFieldDidBeginEditing, the same ghosting effect happens. Both the placeholder text and the input shows.
I have tried setting placeholders and text to nil in textFieldDidBeginEditing, but to no avail.
The table view uses michaeltyson's TPKeyboardAvoidingTableView.
edit Added my cellForRowAtIndex:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"Cell%d", indexPath.row ]];
cell.textLabel.text = _tableData[indexPath.row];
if (indexPath.row == 0) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.placeholder = @"(Required)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 1) {
UILabel *textField = [[UILabel alloc] initWithFrame:CGRectMake(110, 6, 185, 30)];
textField.text = @"(Required)";
textField.textColor = [UIColor lightGrayColor];
textField.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:textField];
secondCellField = textField;
secondCell = cell;
} else if (indexPath.row == 2) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 3) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 4) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 5) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 6) {
UISwitch *textField = [[UISwitch alloc] initWithFrame:CGRectMake(210, 8, 50, 30)];
[textField addTarget:self action:@selector(segwayToWork) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:textField];
_workSwitch = textField;
}
return cell;
The problem here is that everytime a cell gets reloaded, you initialize a new text view which won't have the text that was previously entered. The best solution to this problem is for you to keep an NSMutableArray* that stores the user's input. You have different options, i'll just describe the steps for one possible solution:
@property (strong, nonatomic) NSMutableArray *userData;
and the getter that performs lazy initialisation:
-(NSMutableArray *)userData
{
if(!_userData){
_userData = [[NSMutableArray alloc] initWithCapacity:[self.tableData count]];
for (int i = 0; i < [self.tableData count]; i++)
[_userData addObject:@""];
}
return _userData;
}
tag
to store the row for the particular textfield as follows:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"Cell%d", indexPath.row ]];
if(cell == nil)
cell = [[UITableViewCell alloc] init];
cell.textLabel.text = _tableData[indexPath.row];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
textField.delegate = self;
textField.tag = indexPath.row;
if (indexPath.row == 0) {
textField.placeholder = @"(Required)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 1) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(110, 6, 185, 30)];
label.text = @"(Required)";
label.textColor = [UIColor lightGrayColor];
label.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:label];
secondCellField = label;
secondCell = cell;
} else if (indexPath.row == 2) {
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 3) {
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 4) {
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 5) {
textField.placeholder = @"(Optional)";
[cell.contentView addSubview:textField];
} else if (indexPath.row == 6) {
UISwitch *switch = [[UISwitch alloc] initWithFrame:CGRectMake(210, 8, 50, 30)];
[switch addTarget:self action:@selector(segwayToWork) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:switch];
_workSwitch = switch;
}
if(![[self.userData objectAtIndex:indexPath.row] isEqualToString:@""]){
NSLog(@"%@ at indexPath.row %d",[self.userData objectAtIndex:indexPath.row], indexPath.row);
textField.placeholder = nil;
textField.text = [self.userData objectAtIndex:indexPath.row];
}
return cell;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
self.userData[textField.tag] = textField.text;
return YES;
}
Now when a cell will be reloaded, it will first check whether there was already a user input, and if there was one, it will set the placeholder to nil and will instead show just the user input.