有没有一种通用的方法来通知所有在 UIViewController 级别开始和移动的触摸?

Posted

技术标签:

【中文标题】有没有一种通用的方法来通知所有在 UIViewController 级别开始和移动的触摸?【英文标题】:Is there a general way to be notified of all touches began and moved at the UIViewController level? 【发布时间】:2015-01-19 18:32:46 【问题描述】:

我有一个UIViewController 子类,其视图具有复杂的后代视图层次结构,包括UIButtons 和UISlider。我想在 5 秒后在没有任何用户交互的情况下隐藏控件。 5 秒部分很简单:使用计时器。不过,我不知道检测用户交互的一般方法。

我的第一个想法是在UIViewController 子类中覆盖UIRespondertouchesBegan:withEvent:touchesMoved:withEvent:,但是当用户点击UIButton 或拖动@ 上的旋钮时不会调用它们987654329@.

如果我能提供帮助,我不想做的是注册每个控件的通知。我也不想惹UIWindow。还有其他想法吗?

【问题讨论】:

【参考方案1】:

我最终创建了一个连续的手势识别器,它可以识别何时至少有一次触摸。我将它添加到 UIViewController 子类的视图中,效果很好!我花了很长时间才意识到它需要将 cancelsTouchesInViewdelaysTouchesEnded 都设置为 false 否则它会以某种方式失败。

class TouchDownGestureRecognizer: UIGestureRecognizer 

    override init(target: AnyObject, action: Selector) 
        super.init(target: target, action: action)

        cancelsTouchesInView = false
        delaysTouchesEnded = false
    

    override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) 
        state = .Began
    

    override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) 
        if numberOfTouches() - touches.count == 0 
            state = .Ended
        
    

    override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) 
        if numberOfTouches() - touches.count == 0 
            state = .Cancelled
        
    

    override func shouldBeRequiredToFailByGestureRecognizer(otherGestureRecognizer: UIGestureRecognizer!) -> Bool 
        return false
    

    override func shouldRequireFailureOfGestureRecognizer(otherGestureRecognizer: UIGestureRecognizer!) -> Bool 
        return false
    

    override func canPreventGestureRecognizer(preventedGestureRecognizer: UIGestureRecognizer!) -> Bool 
        return false
    

    override func canBePreventedByGestureRecognizer(preventingGestureRecognizer: UIGestureRecognizer!) -> Bool 
        return false
    


【讨论】:

【参考方案2】:

通过在 viewDidLoad 中调用 setupTapGesture 将 UIGestureRecognizer 添加到您的 UIViewController

- (void)setupTapGesture 

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toggleVisibility)];
    tapGesture.delegate = self;
    [self.view addGestureRecognizer:tapGesture];

然后使用此回调来检测来自按钮、滑块 (UIControl) 的触摸

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer    shouldReceiveTouch:(UITouch *)touch 

        //To ignore touches from Player Controls View
        if ([[touch.view superview] isKindOfClass:[UIControl class]]) 
        
            return NO;
        
        return YES;

【讨论】:

谢谢,这让我走上了正确的道路。我从来没有只使用 gestureRecognizer: shouldReceiveTouch: 让它工作,但是自定义手势识别器可以解决问题。【参考方案3】:

为什么不使用UIGestureRecognizer?。您可能需要为不同的可能交互类型(例如按住和滑动)设置几个不同的交互类型,但是您可以让它们都调用相同的函数来保持屏幕打开并重置计时器。

【讨论】:

以上是关于有没有一种通用的方法来通知所有在 UIViewController 级别开始和移动的触摸?的主要内容,如果未能解决你的问题,请参考以下文章

在没有后台任务的情况下增加徽章值

有没有一种简单的方法来编辑/修改 UILocalNotification

描述emacs中的绑定过滤

有一种方法可以在 Node.JS 中为所有设备推送通知吗?

Slack:有没有办法禁用所有@channel 通知

iOS 推送通知 - 向所有人发送消息