You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发中为临时UIView添加向下滑动关闭手势无响应如何解决

手势无法触发的原因及解决方案

核心原因

  • 属性拼写错误:你代码里写的toastView.isUserInteractionAvailable = true是错误的,UIView开启用户交互的正确属性是isUserInteractionEnabled,写错属性导致toastView根本不接收任何触摸事件,手势自然无法触发。
  • 动画默认禁用交互:UIKit的UIView.animate方法默认会在动画执行过程中禁用视图的用户交互,你提前添加了延迟duration后执行的消失动画,在等待动画执行和动画运行的整个周期内,toastView的交互都被默认关闭了。
  • 子视图拦截触摸:如果AnimationView或者UILabel开启了用户交互,会优先吃掉触摸事件,不会传递给父视图的手势识别器。
  • 自动消失动画未取消:就算手势触发了,未取消的预加消失动画也可能导致后续逻辑异常。

修复步骤

  1. 修正用户交互属性配置
    把错误的交互属性替换为正确写法,同时关闭不需要交互的子视图的交互能力,避免触摸被拦截:
// 替换错误的isUserInteractionAvailable
toastView.isUserInteractionEnabled = true
// 子视图不需要交互就关闭,避免拦截
animationView.isUserInteractionEnabled = false
messageLabel.isUserInteractionEnabled = false
  1. 给动画添加允许交互的参数
    把原有自动消失的延迟动画改用DispatchWorkItem实现,方便手动取消,同时给所有动画添加.allowUserInteraction选项:
// 弹出动画
UIView.animate(withDuration: 0.2, delay: 0, options: .allowUserInteraction, animations: {
    toastView.frame.origin.y = self.view.frame.size.height - self.view.safeAreaInsets.bottom - 70
}, completion: {_ in
    animationView.play()
})

// 自动消失逻辑改用DispatchWorkItem实现,你需要把dismissWorkItem声明为当前控制器的属性
self.dismissWorkItem = DispatchWorkItem { [weak self] in
    guard let self = self, let toastView = self.view.viewWithTag(1474) else { return }
    UIView.animate(withDuration: 0.2, delay: 0, options: .allowUserInteraction, animations: {
        toastView.center.y = self.view.frame.size.height + 50
    }, completion: {_ in
        toastView.removeFromSuperview()
    })
}
DispatchQueue.main.asyncAfter(deadline: .now() + duration, execute: self.dismissWorkItem!)
  1. 修改手势触发方法,手动取消自动消失任务
@objc func dismissToast(_ sender: UIGestureRecognizer) {
    guard let toastView = sender.view else { return }
    // 取消待执行的自动消失任务
    self.dismissWorkItem?.cancel()
    // 移除所有已添加的动画
    toastView.layer.removeAllAnimations()
    
    UIView.animate(withDuration: 0.2, delay: 0, options: .allowUserInteraction, animations: {
        toastView.center.y = self.view.frame.size.height + 50
    }, completion: {_ in
        toastView.removeFromSuperview()
    })
}
  1. 可选:解决手势冲突
    如果和页面其他手势存在冲突,可以遵守UIGestureRecognizerDelegate协议,添加以下代码:
swipeDownGesture.delegate = self

// 实现代理方法
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

内容的提问来源于stack exchange,提问作者goatofanerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 19:09:03