InteractivePopGestureRecognizer返回时自定义键盘提前弹出问题求助
解决InteractivePopGesture返回时自定义键盘提前弹出的问题
方案一:监听手势状态精准控制键盘
手势返回是渐进式过程,仅靠进度判断容易失效,需根据手势的完整状态周期处理:
- 在聊天页面的
viewDidLoad中添加手势监听:if let popGesture = navigationController?.interactivePopGestureRecognizer { popGesture.addTarget(self, action: #selector(handlePopGesture(_:))) } - 实现手势状态处理方法:
@objc private func handlePopGesture(_ gesture: UIGestureRecognizer) { switch gesture.state { case .began: // 手势启动立即隐藏键盘,避免过渡中提前弹出 hideCustomKeyboard() case .ended, .cancelled, .failed: // 仅当手势完成且成功返回聊天页时,延迟恢复键盘 if gesture.state == .ended && navigationController?.viewControllers.contains(self) == true { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.showCustomKeyboard() } } default: break } }
方案二:延迟viewWillAppear中的键盘触发逻辑
聊天页的viewWillAppear会在手势过渡过程中提前触发,可通过标记区分是否为手势返回场景:
- 添加属性标记手势状态:
private var isPopGestureActive = false - 结合手势监听更新标记:
if let popGesture = navigationController?.interactivePopGestureRecognizer { popGesture.addTarget(self, action: #selector(handlePopGesture(_:))) }@objc private func handlePopGesture(_ gesture: UIGestureRecognizer) { isPopGestureActive = gesture.state == .began || gesture.state == .changed if [.ended, .cancelled, .failed].contains(gesture.state) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.isPopGestureActive = false if self.navigationController?.topViewController == self { self.showCustomKeyboard() } } } } - 修改
viewWillAppear逻辑:override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 非手势触发的场景(如首次进入)直接弹出键盘 if !isPopGestureActive { showCustomKeyboard() } }
方案三:通过导航代理统一控制过渡前后的键盘状态
借助导航控制器的生命周期钩子,在过渡开始前隐藏键盘,过渡完成后再恢复:
- 实现
UINavigationControllerDelegate协议方法:func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { if operation == .pop { // 启动返回过渡时隐藏键盘 (fromVC as? ChatViewController)?.hideCustomKeyboard() } return nil // 使用系统默认过渡动画,也可自定义 } func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { // 过渡完成后,若回到聊天页则弹出键盘 DispatchQueue.main.async { (viewController as? ChatViewController)?.showCustomKeyboard() } } - 记得在聊天页或导航控制器中设置
navigationController?.delegate = self
注:上述代码中的
hideCustomKeyboard()和showCustomKeyboard()需替换为你项目中实际控制自定义键盘显示/隐藏的方法;0.1秒延迟是为了等待过渡动画完成,可根据实际效果调整时长。
内容的提问来源于stack exchange,提问作者daniel
相关产品推荐
相关产品推荐

