获取UITableViewCell中UITextField所在的行

4

我有两个 UITextFields 在一个自定义单元格的 UITableView 内。 我需要编辑和存储这些文本字段的值。 当我点击一个 UITextField 时,我需要知道它所属的行,以便将值保存到本地数组的正确记录中。 如何获取textField的行索引? 我尝试过:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{

     currentRow = [self.tableView indexPathForSelectedRow].row;


}

但是当我点击UITextFieldRow内部时,currentRow不会改变。只有当我点击(选择)整个行时,它才会改变...

5个回答

7

文本字段未向表视图发送触摸事件,因此indexPathForSelectedRow无法正常工作。您可以使用以下方法:

CGPoint textFieldOrigin = [self.tableView convertPoint:textField.bounds.origin fromView:textField];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:textFieldOrigin]; 

这是一个强大的解决方案,我想。被接受的答案具有超级视图层次结构的依赖性,并且在特定于操作系统的情况下,所以现在对我来说是一个糟糕的解决方案。 - Tirth

5
在iOS 8中,我发现模拟器和设备有不同数量的superviews,因此这个方法更加通用,适用于所有版本的iOS:
UIView *superview = textField.superview;
while (![superview isMemberOfClass:[UITableViewCell class]]) { // If you have a custom class change it here
    superview = superview.superview;
}

UITableViewCell *cell =(UITableViewCell *) superview;
NSIndexPath *indexPath = [self.table indexPathForCell:cell];

4

试试这个

//For ios 7

UITableViewCell *cell =(UITableViewCell *) textField.superview.superview.superview;
NSIndexPath *indexPath = [tblView indexPathForCell:cell];


//For ios 6

UITableViewCell *cell =(UITableViewCell *) textField.superview.superview;
NSIndexPath *indexPath = [tblView indexPathForCell:cell];

3
为什么要使用三个父视图? - gdm
表格视图单元格的层次结构发生了变化,因此需要添加额外的 .superview。 - Kalpesh
你能告诉我这个更改的说明文档在哪里吗?谢谢。 - gdm
3
虽然这种方法有效,但它注定会失败,并在苹果做出更改时引起问题... - anders

0

1>你可以通过在CellForRowAtIndexPath中以编程方式创建文本字段,并将文本字段的标记设置为indexpath.row来实现它。然后,在textFieldDidBeginEditing中,您只需获取textField.tag并实现您想要的功能。

2>另一种方法是在一个表视图中拥有2个自定义单元格。这样,您可以单独放置文本字段并从实用程序面板中设置它们的标记。


不行,因为我只有2秒钟。 - gdm
我理解你有两个文本框。但是,不要直接将文本框放入单元格中,而是通过编程方式创建它们。 - Ravi_Parmar
你有多少个文本框并不影响确定你在哪一行,让所有的文本框都与该行具有相同的标签。 - A'sa Dickens
他需要单独识别文本框,所以我建议他在 CellForRowAtIndexPath 中创建后为文本框打标签,并在 textFieldDidBeginEditing 中使用标签识别文本框。 - Ravi_Parmar

0
我所做的是创建一个自定义单元格,将需要的自定义UI元素放置在其中,并创建一个属性indexPath,当单元格被出列时设置该属性。然后我将indexPath传递给didSet中的自定义元素。
class EditableTableViewCell: UITableViewCell {

    @IBOutlet weak var textField: TableViewTextField!

    var indexPath: IndexPath? {
       didSet {
           //pass it along to the custom textField
           textField.indexPath = indexPath
        }
    }
}


class TableViewTextField: UITextField {
     var indexPath: IndexPath?
}

在 TableView 中:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "EditableCell") as! EditableTableViewCell
        cell.indexPath = indexPath
        return cell
}

然后我实现了UITextFieldDelegate协议,由于textField有它的indexPath,你总是知道它来自哪里。 不确定设置代理的最佳位置在哪里。最简单的方法是在单元格被出列时设置它。

override func textFieldDidEndEditing(_ textField: UITextField) {
    guard let myTextField = textField as? TableViewTextField else { fatalError() }
    guard let indexPath = myTextField.indexPath else { fatalError() }
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接