如何触摸UITableViewCell外部的某些内容?

时间:2010-03-15 20:09:38

标签: iphone uitableview events touch

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

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

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

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

也许像这样的伪代码:

- (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:但是没有成功。它并不总是被调用。 : - (

3 个答案:

答案 0 :(得分:10)

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

好的,我终于找到了一个完全有效的解决方案。我将UITableView子类化并覆盖了hitTest:withEvent:方法。它可以在表视图中的任何位置调用,唯一的其他可能的触摸是在导航栏或键盘中,tableview的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];   
}    

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

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

耶!

答案 1 :(得分:0)

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

  • 如果您已经是UITableViewCell的子类,请在那里覆盖touchesBegan:withEvent:
  • 如果您使用的是标准的UITableViewCell,请在UITableView的委托中实现tableView:didSelectRowAtIndexPath

答案 2 :(得分:0)

这是一个非常好的解决方案,我在网上找到的最好的解决方案。我发现的唯一一个小问题是,如果你从一个带有文本字段的单元格转到另一个单元格,键盘就会解散并重新出现,从而产生一种生涩的动画。