如何创建一个 30 行的 UITableView,而不是静态地执行它,并在每一行上接受 UITextField 输入?

How can I create a 30 row UITableView, without doing it statically, and accept UITextField input on each row?

通常情况下,如果我想将 UITextField 作为 UITableViewCell 的一部分,我可能会使用 a) 静态行或 b) 我会在情节提要中创建单元格,输出单元格并将字段输出到我的 ViewController,然后将单元格拖到 "Table View" 之外,但将其保留在场景中。

但是,我需要创建一个视图,我可以在其中接受来自 28 个不同事物的输入。我不想输出 28 个不同的 UITextField。

我想动态地执行此操作,以使其更容易。所以我创建了一个带有标签和 UITextField 的自定义 UITableViewCell。

我的 ViewController 有两个数组。

@property (nonatomic, strong) NSArray *items;
@property (nonatomic, strong) NSArray *itemValues;

我的 cellForRowAtIndexPath 看起来像这样...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *cellIdentifier = @"ItemCell";
    MyItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    if (!cell) {
        cell = [[MyItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        [cell.itemValue addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    } else {
        if (![cell.itemValue actionsForTarget:self forControlEvent:UIControlEventEditingChanged]) {
        [cell.itemValue addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
        }
    }

    cell.item.text = [self.items objectAtIndex:indexPath.row];
    cell.itemValue.text = [self.itemValues objectAtIndex:indexPath.row];

    return cell;
}

- (void)textFieldDidChange:(id)sender
{
    NSLog(@"textFieldDidChange: %zd", [self.tableView indexPathForSelectedRow].row);
}

这被证明是有问题的。 textFieldDidChange 始终 returns [self.tableView indexPathForSelectedRow].row 为 0,因为单元格当然从未被选中。我对如何找出哪一行的 UITextField 已被编辑感到困惑,这样我就可以更新相应的 itemValues 数组。

UITableView 有一个巧妙的方法,可以将 tableView 中的点转换为 indexPath,indexPathForRowAtPoint:

首先,您必须将 textField 的原点转换为 UITableView 的框架。

- (void)textFieldDidChange:(UITextField *)sender
{
    CGPoint textFieldOriginInTableView = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:textFieldOriginInTableView];
    if (indexPath) {
        NSLog(@"TextField at indexPath %@ did change", indexPath);
    }
    else {
        NSLog(@"Error: Can't calculate indexPath");
    }
}

最简单的方法是 tag 带有 indexPath.row 的文本字段,然后通过委托方法中的 [sender tag] 取回它。