如何在控制器基类检测用户交互以实现指定页面session超时,无需子类化UIApplication
实现方案
你可以通过基类添加兼容型全局手势+事件传递链适配的方式实现需求,不需要子类化UIApplication,具体实现逻辑如下:
方案1:基类添加穿透型全局手势(推荐)
这种方式可以覆盖99%的交互场景,且不会影响原有页面的交互逻辑:
- 首先在公共基类控制器的
viewDidLoad方法中添加手势识别器,设置cancelsTouchesInView = false避免拦截原有交互:
// Swift 示例 override func viewDidLoad() { super.viewDidLoad() // 添加通用手势识别器 let monitorGesture = UITapGestureRecognizer(target: self, action: #selector(resetInactivityTimer)) monitorGesture.cancelsTouchesInView = false monitorGesture.delegate = self self.view.addGestureRecognizer(monitorGesture) // 如果需要覆盖滑动、滚动类交互,可额外添加UIPanGestureRecognizer、UISwipeGestureRecognizer,配置规则同上 // 初始化超时计时器 setupTimer() }
- 实现手势代理方法,允许和页面原有手势同时触发,解决冲突问题:
extension BaseTimeoutViewController: UIGestureRecognizerDelegate { func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } }
- 计时器逻辑实现:
private var inactivityTimer: Timer? // 可自定义超时时长,示例为5分钟 private let timeoutThreshold: TimeInterval = 300 private func setupTimer() { inactivityTimer = Timer.scheduledTimer(withTimeInterval: timeoutThreshold, repeats: false, block: { [weak self] _ in // 触发超时逻辑 self?.handleSessionTimeout() }) } @objc private func resetInactivityTimer() { // 重置计时器 inactivityTimer?.invalidate() setupTimer() } private func handleSessionTimeout() { // 你的超时业务逻辑,比如弹出提示、退回登录页等 }
- 页面消失时销毁计时器避免内存泄漏:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) inactivityTimer?.invalidate() inactivityTimer = nil }
方案2:补全触摸事件捕获
如果需要覆盖非手势类的触摸交互,可以重写基类的UIResponder触摸方法,和方案1结合使用补全场景:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) resetInactivityTimer() } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesMoved(touches, with: event) resetInactivityTimer() } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesEnded(touches, with: event) resetInactivityTimer() }
注意:该方法无法捕获UIControl类控件(按钮、开关等)的点击事件,因为控件会优先消费触摸事件不会向上传递,需要搭配方案1的手势使用。
内容的提问来源于stack exchange,提问作者Shruti
相关产品推荐
相关产品推荐

