自定义Chargement类弹窗在含UICollectionView的ViewController中无法关闭
解决«Chargement»弹窗在带UICollectionView的ViewController中无法关闭的问题
这种情况我之前踩过坑,大概率是视图层级、事件响应链或者实例引用/线程问题导致的,咱们一步步排查解决:
1. 检查弹窗的父视图层级
你会不会把弹窗误加到了UICollectionView或者它的子视图上?如果是这样,UICollectionView的滚动交互、视图复用机制会拦截关闭按钮的点击事件,甚至导致弹窗实例状态异常。
解决方法:
- 确保弹窗添加到当前ViewController的根view,或者更上层的
UIWindow上:// Swift示例:加到当前VC的根view self.view.addSubview(chargementView) // 或者加到keyWindow(适配iOS13+) if let window = UIApplication.shared.connectedScenes .filter({$0.activationState == .foregroundActive}) .map({$0 as? UIWindowScene}) .compactMap({$0}) .first?.windows.first(where: {$0.isKeyWindow}) { window.addSubview(chargementView) } - 添加后把弹窗层级调到最上层,避免被collectionView覆盖:
self.view.bringSubviewToFront(chargementView) // 加到window上同理 window?.bringSubviewToFront(chargementView)
2. 验证事件响应链是否正常
有时候UICollectionView的userInteractionEnabled可能被意外设为false,或者弹窗的关闭按钮/自身的交互开关没打开,导致点击事件无法传递。
排查步骤:
- 确认关闭按钮的
isUserInteractionEnabled为true:closeBtn.isUserInteractionEnabled = true - 检查弹窗自身的
isUserInteractionEnabled是否开启,避免整个弹窗无法接收事件。 - 如果用了“点击空白处关闭”的手势,记得把手势的
cancelsTouchesInView设为false,防止拦截按钮点击:let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissChargement)) tapGesture.cancelsTouchesInView = false chargementView.addGestureRecognizer(tapGesture)
3. 确认关闭操作在主线程执行
UI操作必须在主线程执行,如果你的关闭方法是在后台线程调用的(比如网络请求回调直接触发),就会导致弹窗无响应。
解决方法:
- 关闭弹窗时强制切换到主线程:
DispatchQueue.main.async { self.chargementView.dismiss() // 假设你的关闭方法是dismiss }
4. 检查弹窗实例的引用是否被提前释放
如果在带UICollectionView的VC里,你用局部变量创建Chargement实例,可能会因为ARC自动释放导致实例被销毁,调用关闭方法时已经无效。
解决方法:
- 在ViewController中声明强引用属性持有弹窗实例:
class CollectionVC: UIViewController { private var chargement: Chargement? // 强引用持有 func showLoading() { chargement = Chargement() chargement?.show() } func hideLoading() { chargement?.dismiss() chargement = nil // 用完后置空释放资源 } }
5. 排查手势冲突问题
UICollectionView自带滚动手势,可能和弹窗的点击手势冲突,导致关闭操作没被触发。
解决方法:
- 给弹窗的手势设置代理,允许和collectionView的手势同时识别:
extension Chargement: UIGestureRecognizerDelegate { func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } }
你可以按照这个顺序逐一排查,大概率能解决问题!
内容的提问来源于stack exchange,提问作者diego
相关产品推荐
相关产品推荐

