如何从编辑后的UITextField中获取UITableViewCell的索引

7
我正在开发一个基于iPhone的BI项目。
我在UITextViewCell中有一个UITextFieldUITextFieldDelegate指向我的UITableViewController,我没有对UITextViewCellUITextField进行任何子类化。
现在,在委托结束编辑文本字段后。
  -(void)textFieldDidEndEditing:(UITextField*)textField

我需要知道当前正在编辑的单元格的行索引,有没有办法获取文本字段的父单元格?或者我是否可以在创建单元格时为文本字段设置一些属性,例如'rowIndex'? 我真的需要这个值以保存新文本。

谢谢。愿原力与你同在。

8个回答

10

随着iOS 7中UITableViewCell类的更改,您需要一种更动态的方式来获取父单元格。您可以使用以下片段(应将其放在textFieldDidEndEditing:委托方法中)来访问UITextField所在的单元格。

// Get the cell in which the textfield is embedded
id textFieldSuper = textField;
while (![textFieldSuper isKindOfClass:[UITableViewCell class]]) {
    textFieldSuper = [textFieldSuper superview];
}
// Get that cell's index path
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)textFieldSuper];

这段代码可以在iOS 6和iOS 7中都正常工作。


我喜欢它。即使更改单元格的视图层次结构,它也总是有效的。 - Fidel López

8
你真正想问的问题是如何知道在用户输入表格单元格中的文本字段时,将更改保存到数据模型的哪个位置。
@Ole Begemann的建议使用tag属性是完全有效的。这取决于你的数据模型。如果你只需要一个整数来标识值在模型中的位置,则将该整数存储在每个文本字段的tag属性中即可。由于你没有使用sections,行索引等同于拥有完整的indexPath。
请记住,所有视图都有一个tag属性。因此,你可以将行索引存储在cell.contentView.tag中,将列索引存储在textField.tag中。从文本字段中,你可以使用textField.superview获取contentView。如果不同的视图是textField的superview,请使用该视图代替。
如果你需要比这更复杂的内容来标识在模型中保存文本字段内容的位置,那么你需要做一些不同的事情。我会子类化UITableViewCell或UITextField,并在子类中定义一个属性来存储所需的任何信息。

谢谢,这个确实解决了我的问题,可以得到行索引。 - Zhao Xiang
这对我有用,但我必须执行(CustomCell *)textField.superview.superview来获取单元格本身,可能是因为textField在contentView或其他地方。 - John H
是的,我确实提到了。请看第三段。 - XJones

4
如果您将UITextField添加到UITableViewCell中作为子视图,那么您可以通过UITextFieldsuperview属性访问UITableViewCell
请尝试以下操作。
UITableViewCell* myCell = (UITableViewCell*)textField.superview ;

如果你遇到任何问题,请告诉我。

编辑:

你可以从UITextField的标签属性中获取行。

NSUInteger  myRow = myTextField.tag;

正如您所说,您的应用程序不支持具有多个部分,这意味着您所有的行都在第0部分。

NSUInteger  mySection = 0;

现在从上面的信息构建一个NSIndexPath实例。
NSIndexPath *myIndexPath =[NSIndexPath indexPathForRow:myRow  inSection:mySection]; //Do'nt release myIndexPath instance.

UITableViewCell* myCell = [myTableView cellForRowAtIndexPath:myIndexPath];

现在你有一个位于UITableView中myRow的myCell。

那么我该如何获取单元格的索引呢?该单元格似乎没有indexPath属性。 - Zhao Xiang
由于myTextField.tag已经用于列,我将采用@XJones的解决方案来保存行到myCell.tag中。我想感谢你们所有人,但似乎我只能选择一个答案。 - Zhao Xiang

3

对于iOS 7,情况有些不同。 如果aTextField是一种UITextField对象, iOS 6: [[aTextField superView] superView]

iOS 7: [[[aTextField superView] superView] superView]

苹果在UITableViewCell和其contentView之间添加了一个ScrollView。

编辑:在iOS 8中,ScrollView消失了。

iOS 8: [[aTextField superView] superView]


2
正如其他人建议的那样,您可以通过访问文本字段的父视图来获取当前单元格。从那里,您可以使用UITableView方法-indexPathForCell:轻松找到当前单元格的索引路径。
更新
尽管我仍然认为上述方法是最简单和最好的方法,但可能会在大型表视图中导致减速(如果-indexPathForCell:涉及线性搜索)。我刚刚读到另一个有趣的想法:将部分和行表示为无符号短整数,将它们打包成单个整数并将结果存储在视图(文本字段)的标记属性中(source)。

我认为'indexPathForCell:'可能会很慢,因为它可能会在'UITableView'的单元格中搜索单元格。所以我会选择@XJones的方法。谢谢。 - Zhao Xiang
@赵翔:你不知道这一点(文档中没有说明正在发生什么)。我们所知道的是,索引路径可能已经存储在单元格中。不要过早地进行优化;尝试两种方法,看看哪种方法在易用性和速度方面达到最佳平衡。 - Cameron Spickert
我之前以为如果NSIndexPath存储在单元格中,那么访问方式应该是类似于myCell.indexPath的,但是现在我们需要通过访问UITableView来获取单元格的NSIndexPath。所以我认为应该是通过搜索来实现的,这很合乎逻辑,对吧? - Zhao Xiang
@赵翔:就像我所说的,个人认为在尝试之前不应该做出假设。不过还有很多其他方法可以实现此目的,所以采用最适合你的方式即可 =) - Cameron Spickert

1

tableView:cellForRowAtIndexPath: 中返回单元格时,您可以将 textfield.tag 设置为行索引。


然后他将不得不考虑另一个可以标识单元格的数字。 - Ole Begemann
@Ole Begemann,我认为标签是用于在同一单元格中标识不同控件的ID,不是吗?而我使用它来标识同一UITableViewCell中的不同UITextField。还有其他属性可以设置吗?谢谢。 - Zhao Xiang
@Jhaliya:我没有多个部分,但是在一个UITableViewCell中有多个UITextFields。有什么建议吗? - Zhao Xiang
你可以将tag属性用于任何你想要的东西。 - Ole Begemann
@赵翔:如果你没有多个部分,并且不会影响任何数量的UIViewField,那么你应该选择@Ole Begemann的解决方案,因为行是唯一的。 - Jhaliya - Praveen Sharma
@Ole Begemann,@Jhaliya:每个单元格中我有3个“UITextFields”,我已经使用“tag”属性来标识列,我想我需要另一个属性来标识行,对吧? - Zhao Xiang

0

实际上不需要担心当前正在编辑的单元格索引是什么。我正在使用这段代码

UIView *tableViewCellView = [[field superview] superview];
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
     // Need to traverse one step more up the visual tree
     tableViewCellView = [tableViewCellView superview];
}
[self.tableView scrollRectToVisible:[tableViewCellView frame] animated:YES];

结合BSKeyboardControls委托方法,成功将所选字段滚动到视图中。已在iOS5及以上版本进行测试


0
请注意,如果您有一个很长的单元格表格,由于UITableView的框架大小,这些单元格可能会被释放。
由于iOS重用单元格,如果您有多个相似的单元格,请尝试执行以下操作:开始编辑单元格,点击UITextField,滚动到另一个单元格,直到所选的UITextField超出视图范围,现在查看-(void)textFieldDidEndEditing:(UITextField*)textField方法中发生了什么。
您会注意到,textFiled.superview是一个空指针,因为该单元格已被释放,您无法再访问它。
我想到的唯一解决方案是通过-(void)textFieldDidBeginEditing:(UITextField*)textField方法将您需要的单元格属性存储在属性中。

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