Iphone 我如何判断我的UITableViewCell之外的内容何时被触摸?

Iphone 我如何判断我的UITableViewCell之外的内容何时被触摸?,iphone,uitableview,events,touch,Iphone,Uitableview,Events,Touch,类似于,我有一个自定义的UITableViewCell子类,它有一个UITextField。它可以正常工作,除了当用户触摸不同的表视图单元格或表外的其他内容时,键盘不会消失。我正试图找出当手机外的东西被触碰时的最佳位置,然后我可以在文本字段中调用resignFirstResponder 如果UITableViewCell可以接收其视图之外的触摸事件,那么它可以辞职FirstResponder本身,但我看不到任何方法可以在单元格中获取这些事件 EDIT:我在UITableViewCell子类中尝试

类似于,我有一个自定义的UITableViewCell子类,它有一个UITextField。它可以正常工作,除了当用户触摸不同的表视图单元格或表外的其他内容时,键盘不会消失。我正试图找出当手机外的东西被触碰时的最佳位置,然后我可以在文本字段中调用resignFirstResponder

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

EDIT:我在UITableViewCell子类中尝试了这个方法(如下),但它不起作用,我认为这是因为如果事件由控件处理,则不会调用ToucheSBegind:withEvent:。我想我需要在事件被发送到响应链之前捕获它们

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

可能类似于以下伪代码:

- (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:找到了答案(我甚至把它作为答案发布了出来),但那没有成功。它并不总是被呼叫-(

我认为您的思路是正确的,但是
touchesbeated:withEvent:
是一个UIResponder方法,因此您实际上必须在UIView子类而不是UIViewController子类中重写它。您的选项包括:

  • 如果您已经在对UITableViewCell进行子类化,请覆盖
    触摸开始:withEvent:
    那里
  • 如果您使用的是标准UITableView单元格,请在UITableView的委托中实现
    tableView:didSelectRowatineXpath
[已编辑:删除了以前不总是有效的尝试,这次成功了]

好的,我终于找到了一个完全有效的解决方案。我将UITableView子类化,并覆盖hitTest:withEvent:method。它被调用用于表视图中任何位置的所有触摸,唯一其他可能的触摸在导航栏或键盘中,而表视图的hitTest不需要知道这些

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

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


耶!

这是一个非常好的解决方案,是我在网上找到的最好的解决方案。我发现的唯一问题是,如果你从一个带有文本字段的单元格切换到另一个单元格,键盘会自动关闭并重新出现,从而产生一个不稳定的动画。

我刚刚开始使用iPhone开发,但“标准”是使键盘消失的方法是在其后面添加一个空白背景,并让其接收一个润色事件。空白背景并不真正适用于表格视图。表格视图中还有其他单元格可以滚动。如果用户编辑顶部可见单元格(显示键盘)中的文本,然后在另一个可视单元格中点击一个按钮,我希望键盘消失。我正在对UITableViewCell进行子类化,但我认为覆盖touchesBegind:withEvent:in不会起作用。我认为该视图之外的触摸不会传递给它。UIViewController是UIResponder的子类,因此我可以在那里覆盖它但我不知道它是否会得到所有的触摸,或者它们是否会被tableview吞没。我可能只需要尝试看看会发生什么。谢谢!啊哈!我从来没有注意到UIViewController是一个UIResponder。但是它在responder链中位于它的视图之上,因此通过覆盖它,你肯定会错过一些触摸。如果你需要捕获它的话对于位于表格单元格之外的按钮,您最好在整个视图上覆盖一个透明的UIButton或UIView。当键盘未显示时,您可以通过设置
userInteractionEnabled=NO
,防止该按钮/视图截获触摸。还有一件事:由于某些原因,它偶尔会崩溃。更改为:如果([activeCell respondsToSelector:@selector(resignFirstResponder)]{[activeCell resignFirstResponder];}我确实在一些应用程序中使用了此选项,但由于一些未知的原因,过了一段时间后,这会导致键盘在用户点击的任何位置(包括键盘上)都消失,阻止他输入任何内容!对用户来说,唯一摆脱这种情况的方法是杀死应用程序并重新启动它…我还有类似的工作代码。我不知道你怎么办,但在我的情况下,如果应用程序进入后台并从后台返回,则会出现@Sylverb编写的情况。我认为hitTests方法只要应用程序运行就可以工作不要去后台。
-(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];   
}    
-(BOOL)resignFirstResponder
{   
    [cTextField resignFirstResponder];  
    return [super resignFirstResponder];
}