简体   繁体   English

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

[英]How can I tell when something outside my UITableViewCell has been touched?

Similar to this question I have a custom subclass of UITableViewCell that has a UITextField. 此问题类似,我有一个UITableViewCell的自定义子类,它有一个UITextField。 Its working fine except the keyboard for doesn't go away when the user touches a different table view cell or something outside the table. 当用户触摸不同的表视图单元格或表格外的某些东西时,除了键盘之外它的工作正常不会消失。 I'm trying to figure out the best place to find out when something outside the cell is touched, then I could call resignFirstResponder on the text field. 我正在试图找出最好的位置来找出单元格外部的东西,然后我可以在文本字段上调用resignFirstResponder。

If the UITableViewCell could receive touch events for touches outside of its view then it could just resignFirstResponder itself but I don't see any way to get those events in the cell. 如果UITableViewCell可以接收其视图之外的触摸事件,那么它可能只是resignFirstResponder本身,但我没有看到任何方法在单元格中获取这些事件。

EDIT: I tried this (below) in my UITableViewCell subclass but it doesn't work, I think because touchesBegan:withEvent: doesn't get called if the event was handled by a control. 编辑: 我在我的UITableViewCell子类中尝试了这个(下面),但它不起作用,我认为因为如果事件由控件处理,touchesBegan:withEvent:不会被调用。 I think I need to catch the events before they get send down the responder chain somehow. 我想我需要在他们以某种方式向响应者链发送之前捕获事件。

The solution I'm considering is to add a touchesBegan:withEvent: method to the view controller. 我正在考虑的解决方案是向视图控制器添加touchesBegan:withEvent:方法。 There I could send a resignFirstResponder to all tableview cells that are visible except the one that the touch was in (let it get the touch event and handle it itself). 在那里,我可以将resignFirstResponder发送到除触摸所在的所有可见的所有tableview单元格(让它获取触摸事件并自行处理)。

Maybe something like this pseudo code: 也许像这样的伪代码:

- (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];
        }
    }
}

I'm not sure if this is the best way to go about this. 我不确定这是否是最好的解决方法。 There doesn't seem to be any way for the tableviewcell itself to receive event notifications for events outside its view. tableviewcell本身似乎没有任何方法可以接收其视图之外的事件的事件通知。

EDIT2: I thought I had an answer (I even posted it as an answer) using hitTest:withEvent: but that didn't work out. 编辑2: 我以为我有一个答案(我甚至将其作为答案发布)使用hitTest:withEvent:但是没有成功。 It doesn't always get called. 它并不总是被调用。 :-( :-(

[Edited: removed previous attempt which didn't always work, this one does] [编辑:删除了之前并不总是有效的尝试,这个尝试]

OK, I finally figured a solution that fully works. 好的,我终于找到了一个完全有效的解决方案。 I subclassed UITableView and overrode the hitTest:withEvent: method. 我将UITableView子类化并覆盖了hitTest:withEvent:方法。 It gets invoked for all touches anywhere in the table view, the only other possible touches are in the navbar or keyboard and the tableview's hitTest doesn't need to know about those. 它可以在表视图中的任何位置调用,唯一的其他可能的触摸是在导航栏或键盘中,tableview的hitTest不需要知道这些。

This keeps track of the active cell in the table view, and whenever you tap a different cell (or non-cell) it sends a resignFirstResponder to the cell going inactive, which gives it a chance to hide its keyboard (or its datepicker). 这会跟踪表视图中的活动单元格,每当您点击不同的单元格(或非单元格)时,它会向不活动的单元格发送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];   
}    

In my UITableViewCell subclasses that have a UITextField, I add the following code to get rid of the keyboard (or date picker, which slides up just like the keyboard): 在我的UITableViewCell子类中有一个UITextField,我添加以下代码来摆脱键盘(或日期选择器,它像键盘一样向上滑动):

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

Yay! 好极了!

I think you're on the right track, but touchesBegan:withEvent: is a UIResponder method, so you'd actually have to override it in a UIView subclass rather than in your UIViewController subclass. 我认为你是在正确的轨道上,但是touchesBegan:withEvent:是一个UIResponder方法,所以你实际上必须在UIView子类中而不是在你的UIViewController子类中覆盖它。 Your options are: 你的选择是:

  • If you're already subclassing UITableViewCell, override touchesBegan:withEvent: there. 如果您已经是UITableViewCell的子类,请覆盖touchesBegan:withEvent:那里。
  • If you're using a standard UITableViewCell, implement tableView:didSelectRowAtIndexPath in your UITableView's delegate. 如果您使用的是标准的UITableViewCell,请在UITableView的委托中实现tableView:didSelectRowAtIndexPath

That is a very good solution, the best I've found on the net. 这是一个非常好的解决方案,我在网上找到的最好的解决方案。 The only glitch I've discovered is that if you go from one cell with a textfield to another, the keyboard dismisses and reappears resulting in a jerky type animation. 我发现的唯一故障是,如果你从一个带有文本字段的单元格转到另一个单元格,键盘就会解散并重新出现,从而产生一种生涩的动画类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何告诉mapCit已触及rightCalloutAccessoryView - How to tell a rightCalloutAccessoryView has been touched for MapKit 如何判断UITableViewCell内的UISwitch何时被点击? - How to tell when a UISwitch inside of a UITableViewCell has been tapped? 如何区分UITableViewCell的哪个部分已被点击 - how can I distinguish which part of UITableViewCell has been clicked 如何确定先前是否已加载UITableViewCell? - How can I determine if a UITableViewCell has been previously loaded? 由我的ViewController实例创建的UITableViewCell实例如何告诉ViewController做某事? - How can an instance of an UITableViewCell, which was created by an instance of my ViewControllers, tell the ViewController, to do something? 我可以检测是否触摸了更高的子视图吗? - Can I detect if higher subview has been touched? 如何告诉我的ViewController视图被触摸? - How do I tell my ViewController a View was touched? UITableViewCell如何在触摸行时更改UIImageView? - UITableViewCell how to change UIImageView when row is touched? 如何检测用户何时刷过可编辑的UITableViewCell? - How can I detect when the user has swiped an editable UITableViewCell? 我如何告诉我的UIView UIViewController中的按钮已被按下? (迅速) - How do i tell my UIView that the button in UIViewController has been pressed? (Swift)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM