在单元格中单击 UITextField 时,DidSelectRowAtIndexPath 的 indexPath 为零

Posted

技术标签:

【中文标题】在单元格中单击 UITextField 时,DidSelectRowAtIndexPath 的 indexPath 为零【英文标题】:indexPath is nil for DidSelectRowAtIndexPath when clicking on UITextField in cell 【发布时间】:2014-04-30 19:07:33 【问题描述】:

我有一个自定义的UITableViewCell,里面有一个UITextField。当使用 iOS 7 目标运行应用程序并单击单元格中的UITextField 时,didSelectRowAtIndexPath 会触发,但indexPathnil。当我在 iOS 6.1 模拟器中运行相同的代码时,indexPath 不是 nil

我的第一个问题是“为什么会发生这种变化?”

我的第二个问题是“获得活动 indexPath 行的最佳方法是什么”,因为我无法再使用 didSelectRowAtIndexPath 获得它?

下面的代码有效,但感觉 hack-ish

-(UITableViewCell *) cellFromEdit: (UITextField *) field 
    UIView *view = field.superview;
    while (view) 
        if ([view isKindOfClass:[UITableViewCell class]])
            return (UITableViewCell *) view;
        view = view.superview;
    
    return nil;


- (void)textFieldDidChange:(UITextField *)theTextField 
    UITableViewCell *cell = [self cellFromEdit:theTextField];
    if (!cell)
        return;
    int row = [tableView indexPathForCell:cell].row;

【问题讨论】:

看看***.com/questions/4030811/… 我没有看到这个。我有一个表格视图,其中包含包含文本字段的单元格。文本字段不会覆盖整个单元格。如果我只在文本字段中点击,didSelectRowAtIndexPath: 甚至不会被调用。如果我确实在文本字段之外点击单元格,则会调用它并且它具有正确的索引路径。 我记得在 ios 7 beta 上看到过这样的错误,但它在更高的 beta 版本中得到了修复。我想这是您的代码中的问题。如果没有看到您的原始代码,我们无法就正确的解决方案提供建议。还要确保文本字段在单元格的内容视图中,否则会发生很多有趣的事情。 【参考方案1】:

使用与this类似的方法,可以得到UITextField在单元格中的索引路径,如下:

-(NSIndexPath *)indexPathForTextField:(UITextField *)textField

    CGPoint textFieldMiddle = CGPointMake(CGRectGetMidX(textField.bounds), CGRectGetMidY(textField.bounds));
    CGPoint point = [textField convertPoint:textFieldMiddle toView:self.tableView];
    return [self.tableView indexPathForRowAtPoint:point];


-(void)textFieldDidChange:(UITextField *)textField

    NSIndexPath *indexPath = [self indexPathForTextField:textField];
    // Now you can update the object at indexPath for your model!

这比依赖tags 或查看superviews 更简洁!

要回答“为什么会发生这种变化?”的问题...

iOS 7 UITableViewCell 层次结构有所不同,因为它现在包含滚动视图或单元格内的其他内容来处理滑动删除。

这是 iOS 7 中视图层次结构的转储:

<CustomTableViewCell: 0x8cbc9e0; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = W; layer = <CALayer: 0x8cbcc50>>
   | <UITableViewCellScrollView: 0x8c6ceb0; frame = (0 0; 320 44); autoresize = W+H; gestureRecognizers = <NSArray: 0x8c6d0c0>; layer = <CALayer: 0x8cbce50>; contentOffset: 0, 0>
   |    | <UITableViewCellContentView: 0x8cb54e0; frame = (0 0; 320 44); gestureRecognizers = <NSArray: 0x8cbb990>; layer = <CALayer: 0x8cbb7f0>>
   |    |    | <UILabel: 0x8cbbaf0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8cbd000>>
   |    |    | <UITableViewLabel: 0x8cbd210; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8cbd360>>
   |    | <_UITableViewCellSeparatorView: 0x8cc2a10; frame = (15 43.5; 305 0.5); layer = <CALayer: 0x8cc26e0>>

【讨论】:

一个建议。将 CGPointZero 更改为 CGPointMake(5,5) 或类似名称。如果文本字段的顶部位于单元格的顶部,则您可能会从中得到错误的单元格。 我很确定它不会(我现在刚刚尝试过,并且之前在各个地方都使用过这种方法)。如果您想确定更好的解决方案是CGPointMake(CGRectGetMidX(textField.bounds), CGRectGetMidY(textField.bounds)),而不是一些随机数。如果您在文本字段开头,即Y=-5,那么这将是一个问题,但由于您故意设置它,您会知道这一点。

以上是关于在单元格中单击 UITextField 时,DidSelectRowAtIndexPath 的 indexPath 为零的主要内容,如果未能解决你的问题,请参考以下文章

iOS:如何从 tableview 的自定义单元格中的 UITextField 访问值

将单元格中的 UITextField 文本保存到 NSUserDefaults 中?

在自定义单元格中聚焦 UITextfield

如何在可重用的 tableView 单元格中更新 UITextfield 中的文本值,每个单元格中的值不同

当点击自定义 TableView 单元格中的 UITextField 时转到新视图

滚动 UITableView 时自定义单元格中的 UITextField 文本正在更改