如何检测 iOS UIViewController 是不是被交互或触摸

Posted

技术标签:

【中文标题】如何检测 iOS UIViewController 是不是被交互或触摸【英文标题】:How to detect if iOS UIViewController is being interacted with or touched如何检测 iOS UIViewController 是否被交互或触摸 【发布时间】:2017-07-02 11:46:01 【问题描述】:

我有一个特定的 UIViewController,我想阻止 ios 完成的 idleTimer 处理。我知道我可以设置:UIApplication.shared.isIdleTimerDisabled = true 但是,我希望能够设置一个计时器以在固定时间后重新启用正常的系统空闲计时器处理,因此我可以在最短的时间内保持屏幕开启。该应用程序的性质是,您可以打开一个视图并将其用于参考/阅读很长时间。

关键点是我希望每次用户触摸屏幕或与设备交互时都重新启动计时器。所以我需要能够检测用户是否做了任何事情,这样我就可以休息了。

我试图覆盖控制器中的 touchesEnded 方法,但测试表明该方法从未被调用。任何想法都会受到欢迎(在 swift 3 中:)

【问题讨论】:

应用使用Background App Referesh时,是否需要检测屏幕特定的UIViewdetect touch`的触摸? 我只需要检测屏幕的触摸,而不是后台刷新。我还需要在代码中完成它。我想检测整个控制器的视图(以及扩展的子视图),而不仅仅是一个特定的视图。 【参考方案1】:

Swift 3.0:-

需要检测没有IBOutlet 的特定视图的触摸,然后选择特定的UIView,然后转到Attributes Inspector -> View -> tag 并将Integer 设置为任何需要的标签。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

    let touch = touches.first

    let tag = touch?.view?.tag
    if tag == 1
        //Do More....
    else
    //......
    


如果您需要与IBOutlet 联系,请执行以下操作。

这里,@IBOutlet var diamondView: UIView!

if touch?.view == self.diamondView

    //Do More....
else
//......

更新:滚动视图

如果您需要检测滚动视图的触摸,请使用UITapGestureRecognizer。通过故事板拖放到UIViewController 并将delegategestureRecognizers 设置为scroll viewUITapGestureRecognizer。之后只需为UITapGestureRecognizer 创建操作,如下图所示。

以编程方式添加 UITapGesture:-

如果没有上面的截图,下面的代码也可以正常工作。

@IBOutlet var scrollView: UIScrollView!

override func viewDidLoad() 
    super.viewDidLoad()

    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.actionTapOnScrollView(sender:)))
    self.scrollView.addGestureRecognizer(tapGesture)




@objc private func actionTapOnScrollView(sender:UITapGestureRecognizer)
    print("user Touched")

【讨论】:

我试图覆盖 touchesBegantouchesEnded 但他们没有被他的控制器调用。控制器视图中的主视图是一个UIScrollView,它占据了大部分窗口。 感谢您的回答@RAJAMOHAN-S。我希望有一些更低级别的东西(不涉及子分类)。我对这个问题的回答告诉你我最终是如何做到的。 @zkon,谢谢,如果您不犹豫,请通过我的个人资料上的 Skype 将代码 sn-p 发送给我。我会发回适当的解决方案。【参考方案2】:

最后我通过对@RAJAMOHAN-S 的建议进行复合解决方案解决了这个问题。

    我在控制器视图中添加了UIGestureRecognizer。如果在视图中的任何位置有点击,我可以使用它来获取,从而重置我的计时器。

    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(viewTappedHandler)))

    viewTappedHandler 方法设置了我需要的计时器。

    我通过将UIScrollViewDelegate 协议添加到控制器的类声明中,使我的UIController 成为UIScrollView 的代表。

    然后我实现:scrollViewWillBeginDragging(_ scrollView: UIScrollView) 并再次设置时间。这会在滚动视图中拾取点击手势未拾取的动作。

    最后,因为我的滚动视图包含可以打开键盘的其他视图,所以我还需要注册键盘通知并为每次出现重新设置计时器。

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: .UIKeyboardDidHide, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidChange), name: .UIKeyboardDidChangeFrame, object: nil)

我对此并不完全满意,因为未检测到对键盘按键的点击,但我不认为这对这个应用程序来说是一个真正的问题。

PS 我还删除了键盘上的观察者并清除了deinit 上的计时器。

【讨论】:

以上是关于如何检测 iOS UIViewController 是不是被交互或触摸的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 UIViewController 外部的点击/触摸

iOS Dev - 如何检测用户通过按“返回”访问此 UIViewController

检测打开 uiviewcontroller 的父母

检测 UIAlertController 何时被另一个 UIViewController 解除

检测整个屏幕上的触摸

iOS暗光模式不更新UIViewController