是否有一般方法可以通知UIViewController级别开始和移动的所有触摸?

时间:2015-01-19 18:32:46

标签: ios uiviewcontroller uibutton uislider uiresponder

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

我的第一个想法是在UIResponder子类中覆盖touchesBegan:withEvent:的{​​{1}}和touchesMoved:withEvent:,但是当用户点击{{{}时,这些不会被调用1}}或拖动UIViewController上的旋钮。

我不想做的是注册来自每个控件的通知,如果我可以提供帮助的话。我也不想搞砸UIButton。还有其他想法吗?

3 个答案:

答案 0 :(得分:3)

我最终创建了一个连续的手势识别器,可识别何时至少有一次触摸。我将它添加到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
    }

}

答案 1 :(得分:1)

通过在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;
}

答案 2 :(得分:0)

为什么不使用UIGestureRecognizer?您可能必须针对不同的可能交互类型(例如保持和滑动)设置一些不同的交互类型,但是您可以让它们全部调用保持屏幕打开的相同功能并重置计时器。