1

我有一个 uiview,由顶部的地图视图和下面的 uitableview 组成。表格视图中有带有 uitextFields 的单元格和占位符。

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

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

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

表格视图使用michaeltyson 的 TPKeyboardAvoidingTableView

幽灵占位符

编辑 添加了我的 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;
4

3 回答 3

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所以请根据您的要求对其进行自定义。您也可以使用此代码。

于 2013-06-24T11:19:53.610 回答
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

如果您不使用故事板或 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;

然后,您可以只返回“CellCount”numberOrRowsInSection并引用如下行:

if (indexPath.row == NameCell) 
于 2013-06-24T13:00:22.637 回答
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;
 }
  • 使用文本字段的属性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,而只显示用户输入。

于 2013-06-24T14:23:46.973 回答