4

这个问题类似,我有一个 UITableViewCell 的自定义子类,它有一个 UITextField。当用户触摸不同的表格视图单元格或表格外的东西时,它的工作正常,除了键盘不会消失。我试图找出最好的位置来找出何时触摸单元格外的东西,然后我可以在文本字段上调用 ​​resignFirstResponder 。

如果 UITableViewCell 可以接收其视图之外的触摸事件,那么它可以自己 resignFirstResponder ,但我看不到任何方法可以在单元格中获取这些事件。

编辑:我在我的 UITableViewCell 子类中尝试了这个(如下),但它不起作用,我认为是因为 touchesBegan:withEvent: 如果事件由控件处理,则不会被调用。我认为我需要在事件以某种方式发送到响应者链之前捕获这些事件。

我正在考虑的解决方案是向视图控制器添加一个 touchesBegan:withEvent: 方法。在那里,我可以向所有可见的 tableview 单元格发送 resignFirstResponder ,除了触摸所在的单元格(让它获取触摸事件并自行处理)。

也许像这样的伪代码:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchPoint = // TBD - may need translate to cell's coordinates

    for (UITableViewCell* aCell in [theTableView visibleCells]) {
        if (![aCell pointInside:touchPoint withEvent:event]) {
             [aCell resignFirstResponder];
        }
    }
}

我不确定这是否是解决此问题的最佳方法。tableviewcell 本身似乎没有任何方法可以接收其视图之外的事件的事件通知。

EDIT2:我以为我有一个答案(我什至将它作为答案发布)使用 hitTest:withEvent: 但这没有成功。它并不总是被调用。:-(

4

3 回答 3

10

[已编辑:删除了以前并不总是有效的尝试,这个可以]

好的,我终于想出了一个完全有效的解决方案。我继承了 UITableView 并覆盖了 hitTest:withEvent: 方法。它会为表格视图中任何位置的所有触摸调用,唯一可能的其他触摸是在导航栏或键盘中,并且表格视图的 hitTest 不需要知道这些。

这会跟踪表格视图中的活动单元格,并且每当您点击不同的单元格(或非单元格)时,它都会向处于非活动状态的单元格发送一个 resignFirstResponder ,这使它有机会隐藏其键盘(或其日期选择器)。

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    // check to see if the hit is in this table view
    if ([self pointInside:point withEvent:event]) {
        UITableViewCell* newCell = nil;

        // hit is in this table view, find out 
        // which cell it is in (if any)
        for (UITableViewCell* aCell in self.visibleCells) {
            if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
                newCell = aCell;
                break;
            }
        }

        // if it touched a different cell, tell the previous cell to resign
        // this gives it a chance to hide the keyboard or date picker or whatever
        if (newCell != activeCell) {
            [activeCell resignFirstResponder];
            self.activeCell = newCell;   // may be nil
        }
    }

    // return the super's hitTest result
    return [super hitTest:point withEvent:event];   
}    

在具有 UITextField 的 UITableViewCell 子类中,我添加了以下代码以摆脱键盘(或日期选择器,就像键盘一样向上滑动):

-(BOOL)resignFirstResponder
{   
    [cTextField resignFirstResponder];  
    return [super resignFirstResponder];
}

耶!

于 2010-03-16T04:05:18.930 回答
0

我认为你在正确的轨道上,但touchesBegan:withEvent:它是一个 UIResponder 方法,所以你实际上必须在 UIView 子类而不是你的 UIViewController 子类中覆盖它。您的选择是:

  • 如果您已经继承了 UITableViewCell,请覆盖touchesBegan:withEvent:那里。
  • 如果您使用的是标准 UITableViewCell,tableView:didSelectRowAtIndexPath请在 UITableView 的委托中实现。
于 2010-03-15T23:59:19.770 回答
0

这是一个非常好的解决方案,我在网上找到的最好的。我发现的唯一故障是,如果您从一个带有文本字段的单元格转到另一个单元格,则键盘会消失并重新出现,从而导致出现生涩的动画。

于 2010-08-10T23:34:26.423 回答