滚动uitextField时,占位符重新出现 - ios

时间:2013-06-24 10:01:41

标签: ios uitableview uitextfield placeholder redraw

我的uiview包含顶部的地图视图和下面的uitableview。表视图中包含带有占位符的uitextFields的单元格。

当我编辑字段时,占位符会正确消失,但是如果我将uitableviewcells滚动到视线之外(即位于表视图上方的地图视图的“后面”),占位符将与写入该视图的内容一起重新出现。的UITextField。

如果我用普通文本替换占位符,并清除textFieldDidBeginEditing上的文本,则会发生相同的重影效果。占位符文本和输入都显示。

我已尝试在textFieldDidBeginEditing中将占位符和文本设置为nil,但无济于事。

表格视图使用michaeltyson's TPKeyboardAvoidingTableView

Ghost placeholder

修改 添加了我的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;

3 个答案:

答案 0 :(得分:2)

您的问题是为不同的单元格创建了多个TextFields。您需要使用reusable个单元格 像:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
        // allocate the cell:
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
         if (indexPath.row == 0) {
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
    textField.delegate = self;
    textField.tag = 1111;//tag
    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.tag = 1111;//tag
    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.tag = 1111;//tag
    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.tag = 1111;//tag
    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.tag = 1111;//tag
    textField.placeholder = @"(Optional)";
    [cell.contentView addSubview:textField];
} else if (indexPath.row == 5) {
    UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
    textField.tag = 1111;//tag
    textField.delegate = self;
    textField.placeholder = @"(Optional)";
    [cell.contentView addSubview:textField];
} elseif (indexPath.row == 6) {
    UISwitch *textField = [[UISwitch alloc] initWithFrame:CGRectMake(210, 8, 50, 30)];
    textField.tag = 1111;//tag
    [textField addTarget:self action:@selector(segwayToWork) forControlEvents:UIControlEventValueChanged];
    [cell.contentView addSubview:textField];

    _workSwitch = textField;
}

}
cell.textLabel.text = _tableData[indexPath.row];

return cell;

}

我已经尝试重用UITableViewCell所以请根据您的要求进行自定义。你也可以使用这个代码。

答案 1 :(得分:2)

创建新文本字段确实是个问题。您不应在cellForRowAtIndexPath中分配/初始化任何文本字段。

相反,要么制作自定义单元格,要么在故事板文件中使用“动态原型”。为您的文本字段添加标记,以便您轻松配置它。

//above
#define TextFieldTag 42

// in cellForRowAtIndexPath:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
// If @"Cell" is the identifier you specified
// if you have storyboard or a xib, no need to check for cell==nil

UITextField *textField = (UITextField*) [cell viewWithTag:TextFieldTag]; 
// configure the text field based on indexPath.row

如果你没有使用storyboard或xibs,你可以像这样懒惰地实例化文本字段:

UITextField *textField = (UITextField*) [cell viewWithTag:TextFieldTag];
if (!textField) {
   textField = [[UITextField alloc] initWithFrame:textFieldFrame];
   textField.tag = TextFieldTag; 
   // more standard configuration
   [cell.contentView addSubview:textField];
}

顺便说一句,这是另一个提示。您不应该对表视图行进行硬编码。这导致代码不是很易读。你可以在课堂上使用简单的枚举:

typedef enum {
   NameCell, AddressCell, 
   FirstOptionalCell, SecondOptionalCell,
   ThirdOptionalCell, CellCount } TableCell;

然后您可以在numberOrRowsInSection中返回“CellCount”并引用这样的行:

if (indexPath.row == NameCell) 

答案 2 :(得分:1)

这里的问题是,每次重新加载一个单元格时,都会初始化一个新的文本视图,该视图不会包含先前输入的文本。解决此问题的最佳方法是保留存储用户输入的NSMutableArray *。你有不同的选择,我只会描述一个可能的解决方案的步骤:

  • 声明一个NSMutableArray属性,用于存储用户输入,如下所示:
@property (strong, nonatomic)  NSMutableArray *userData;

和执行延迟初始化的getter:

 -(NSMutableArray *)userData
 {
    if(!_userData){
        _userData = [[NSMutableArray alloc] initWithCapacity:[self.tableData count]];
        for (int i = 0; i < [self.tableData count]; i++) 
            [_userData addObject:@""];
    }
    return _userData;
 }
  • 使用textfield的属性tag存储特定文本字段的行,如下所示:
- (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;
}
  • 最后,在您的UITextField委托中,您可以执行以下操作:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    self.userData[textField.tag] = textField.text;
    return YES;
}

现在当重新加载一个单元格时,它将首先检查是否已有用户输入,如果有,则将占位符设置为nil,而只显示用户输入。