UITableView 单元格中的 UITextField 以编程方式成为FirstResponder

Posted

技术标签:

【中文标题】UITableView 单元格中的 UITextField 以编程方式成为FirstResponder【英文标题】:UITextField in UITableView cell becomeFirstResponder programmatically 【发布时间】:2012-10-18 22:44:17 【问题描述】:

我有一个UITextField,原型单元格中有一个标签。当UITableView 正在构建并且上面单元格中的UISwitch 被打开时,UITextField 被设置为第一响应者。 如果应用程序从头开始或已关闭并重新启动,则此方法有效。加载后,[tableView reloadData] 不再触发 becomeFirstResponder

如果稍后通过触摸文本字段UITextField 成为第一响应者,我可以通过按钮、弹出窗口、...触发becomeFirstResponder 事件。 但不再是我的开关了。

关于我可以尝试什么的任何指示?

目前,我使用didSelectRowAtIndexPath 方法来触发弹出窗口。一个很好的副作用是,当我拉起数字键盘时,我可以在弹出窗口中提供一个确定和取消按钮,而不必摆弄键盘上的单独按钮。但这显然是一种解决方法。

这就是我在构建 UITableView 时调用 firstresponder 的方式(每次应用从头开始时都有效):

if ([settings doubleForKey:@"limitDouble"]==0 && [settings boolForKey:@"limitBool"]==YES) 
    [dailyLimitEntry becomeFirstResponder];

dailyLimitEntry 是一个 UITextField,它很强大,所以它会一直存在。

只是为了好玩,我添加了一个按钮并将其连接到我的代码,如下所示:

UITextField *tmp = (UITextField *)[self.view viewWithTag:35];
[tmp becomeFirstResponder];

这也有效。当我将它与开关一起使用时,只有在应用程序新加载到内存中时才会调用它。否则,我的UITextField 不会响应开关。

在第一次cmets之后,我找到了一个方法来检查UITableView是否已经完成重新加载

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
    if([indexPath row] == ((NSIndexPath*)[[settingsTableView indexPathsForVisibleRows] lastObject]).row)
        //end of loading
        //for example [activityIndicator stopAnimating];
        NSLog(@"finished reload");
        NSLog(@"%@",dailyLimitEntry);
        if ([settings boolForKey:@"limitBool"]==YES) 
            UITextField *tmp = (UITextField *)[self.view viewWithTag:35];
            [tmp becomeFirstResponder];
        
    

有趣的是,只有在应用加载后第一次使用开关时才会触发成为第一响应者。最初,开关是关闭的。所以包含UITextField 的单元格尚未绘制。一旦我切换到ONUITextField 就会被绘制在第二个单元格中并成为第一响应者。如果我再次切换OFFON,我仍然会得到我的日志“完成重新加载”,但UITextField 不会成为第一响应者。它快把我逼疯了...... 必须与应用的生命周期有关。

【问题讨论】:

请显示您调用becomeFirstResponder的代码 您有在切换开关时调用的方法吗?如果是,请发布该代码。如果没有,那么您需要进行设置,以便在打开开关时调用 becomeFirstResponder。 我使用了与按钮示例中相同的代码,并带有开关值更改事件。 随着按钮的工作,我认为这是一个时间问题。是否有一些电话可以检查表格视图是否已重新加载数据?我认为它来自正在操作的开关,它要求重新加载表数据,一旦完成,我可以将焦点放在文本字段上。 我的猜测是 willDisplayCell 和 becomeFirstResponder 是两个尝试在主线程上运行的方法,并且 tableView 方法获得更高的优先级,而 becomeFirstResponder 消息被丢弃。尝试延迟调用 [tmp becomeFirstResponder];通过使用 performSelector: afterDelay: 【参考方案1】:

检查单元格的类,而不是检查 indexPath。

以下是我为空白标题单元格调出键盘的操作(当我创建新项目时):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

    if ([cell isKindOfClass:[FDSSampleTitleCell class]]) 
        FDSSampleTitleCell *titleCell = (FDSSampleTitleCell *)cell;
        if (titleCell.titleField.text.length == 0) 
            [titleCell.titleField becomeFirstResponder];
        
    

【讨论】:

以上是关于UITableView 单元格中的 UITextField 以编程方式成为FirstResponder的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 单元格中的 UIButton,例如“删除事件”

UITableView 单元格中的 UITextField 以编程方式成为FirstResponder

重用 uitableview 单元格以及单元格中的子视图

更新 UITableView 单元格中的特定按钮图像

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

单元格中的 UITableView 动画导致平滑滚动中断