当调用 textFieldDidEndEditing 时,应用程序冻结

Posted

技术标签:

【中文标题】当调用 textFieldDidEndEditing 时,应用程序冻结【英文标题】:When textFieldDidEndEditing gets called, the app freezes 【发布时间】:2015-03-22 20:46:27 【问题描述】:

我有一个自定义的UITableView,里面有UITextFields。在cellForRow... 中,我将textFields 委托给了自己。 (在我的主要 VC 课程中。)我从 textField 获取文本的方式是在 textFieldDidEndEditing,然后我将它添加到 mutableArray

然后我会在选择按钮时添加不同的单元格 ID:

- (IBAction)addRow:(id)sender

    NSInteger row = [self.rowArray cound];
    [self.rowArray insertObject:@"anotherCell" atIndex:row];

    NSIndexPath *indexPath = [NSindexPath indexPathForRow:row inSection:0];
    [self.myTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

(在那个cellID中有一个textField,我将delegate设置为self。)

textFieldDidEndEditing 中,我创建了textField.textNSLog,当从最初存在的textField 调用该方法时,它按预期工作。

但是当textFieldDidEndEditinganotherCell 的单元格(添加的单元格)中的textField 调用时,整个模拟器就会冻结。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    NSString *cellID = [self.rowArray objectAtIndex:[indexPath row]];

    customCell *cell = [tableView dequeuereusablecellwithidentifier:cellID forIndexPath:indexPath];

    cell.name.delegate = self; // From cell that is initially there
    cell.phoneNumber.delegate = self; // From the added cell

    return cell;

(如果这令人困惑,或者如果您需要更多代码,请在 cmets 中告诉我。谢谢)

编辑

- (void)textFieldDidEndEditing:(UITextField *)textField

    if (textField.tag <= 9)
    
        NSLog(@"%@", textField.text); // This works
    

    UIView *superview = textField.superview;
    while (![superview isMemberOfClass:[UITableViewCell class]]) 
        superview = superview.superview;
    
    CustomCellClass *cell = (CustomCellClass *)superview;
    NSIndexPath *indexPath = [self.myTableView indexPathForCell:cell];

    if (textField.tag >= 12)
    
        if ([self.inputArray count] > indexPath.row) // So I won't get the error message of [__NSArrayM objectAtIndex:]: index 1 beyond bounds for empty array'
        
            for (NSUInteger i = [self.inputArray count]; i < indexPath.row; i++) 
                [self.inputArray insertObject:@"" atIndex:i];
                NSLog(@"%lu", (unsigned long)i);
            
        

        NSLog(@"%@", self.inputArray);
    

【问题讨论】:

您是否尝试过在该委托回调上使用带有断点的调试器,以查看在应用冻结之前它进入了多远? 您所做的不是使用表格视图的正常方式。对于每种细胞类型,您应该只有一个细胞标识符。所以,如果你只有一个动态原型,你应该只有一个标识符。另外,如果在调用 textFieldDidEndEditing 时出现问题,那么您需要显示该方法中的代码。 刚刚更新[用该方法更新了我的问题。另外,我确实有超过 1 个单元格 id 更新问题,增加textFieldDidEndEditing的方法。另外,我有不止一种细胞类型。 “冻结”是什么意思?表格视图是否不再滚动?发生这种情况时,代码是否到达 if (textField.tag >= 12) 子句?是这样,self.inputArray的日志打印出来了吗? 【参考方案1】:

您的代码在这里陷入无限循环:

while (![superview isMemberOfClass:[UITableViewCell class]]) 
    superview = superview.superview;

因为isMemberOfClass 只会在父视图类是UITableViewCell 时返回true,但如果它是UITableViewCell子类 则不会。如果您将isMemberOfClass 更改为isKindOfClass,它应该可以工作。查看 Apple 文档 here。

【讨论】:

谢谢。顺便说一句,在获取textField的superview时,您发布的内容与此有区别吗:CGPoint pointInTable = [textFIeld convertPoint:CGPointZero toView:_self.myTableView]; NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:pointInTable]; @Edison 我不认为一种解决方案比另一种解决方案有任何特别的优势。就我个人而言,我对递归视图层次结构以找到对单元格的引用感到不舒服,所以我更喜欢其他解决方案,但这只是我个人的偏好。

以上是关于当调用 textFieldDidEndEditing 时,应用程序冻结的主要内容,如果未能解决你的问题,请参考以下文章

tryToPerform:with: 当 keyDown: 被调用时没有被调用

当 UISlider 值改变时会调用啥?

Android:当所有异步调用完成时通知

当我们双击 uitextview 时会调用啥方法

当调用相同的活动时如何防止分数被覆盖

当按钮被禁用然后点击事件调用