UINavigationControllerPaletteClippingView遮挡ImageView致点击关闭失效求助
我之前也踩过iOS 11里这个UINavigationControllerPaletteClippingView抢点击事件的坑!给你几个经过验证的解决思路,按优先级推荐:
1. 把放大视图放到最顶层容器
这个是最稳妥的方案,直接绕过遮挡问题。你可以把放大后的ImageView添加到keyWindow(全局最顶层窗口),或者确保它在当前导航控制器视图的最上层:
@objc func enlargeImage(sender: UITapGestureRecognizer) { guard let originalImage = (sender.view as? UIImageView)?.image else { return } // 创建全屏放大的ImageView let enlargedImageView = UIImageView(image: originalImage) enlargedImageView.frame = UIScreen.main.bounds enlargedImageView.contentMode = .scaleAspectFit enlargedImageView.isUserInteractionEnabled = true // 添加关闭点击手势 let closeTap = UITapGestureRecognizer(target: self, action: #selector(closeEnlargedImage)) enlargedImageView.addGestureRecognizer(closeTap) // 关键:添加到keyWindow确保层级最高 UIApplication.shared.keyWindow?.addSubview(enlargedImageView) // 如果你不想用keyWindow,也可以用导航控制器视图并置顶 // navigationController?.view.addSubview(enlargedImageView) // navigationController?.view.bringSubviewToFront(enlargedImageView) } @objc func closeEnlargedImage(sender: UITapGestureRecognizer) { sender.view?.removeFromSuperview() }
2. 禁用遮挡视图的用户交互(备选,有审核风险)
UINavigationControllerPaletteClippingView是系统私有视图,直接操作可能有App Store审核风险,但应急场景下可以试试:
func disablePaletteClippingView() { guard let navView = navigationController?.view else { return } // 遍历导航控制器子视图找到目标视图 for subview in navView.subviews { if subview.className == "UINavigationControllerPaletteClippingView" { subview.isUserInteractionEnabled = false break } } }
你可以在viewDidAppear(_:)或者触发放大操作前调用这个方法,但要做好审核被拒的心理准备,优先用方案1。
3. 改用全屏背景容器包裹放大视图
给放大的ImageView套一个全屏的背景视图,把整个容器加到顶层,这样点击背景也能关闭,同时彻底避开遮挡:
@objc func enlargeImage(sender: UITapGestureRecognizer) { guard let originalImage = (sender.view as? UIImageView)?.image else { return } // 创建全屏背景(可加半透明效果) let backgroundView = UIView(frame: UIScreen.main.bounds) backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.8) backgroundView.isUserInteractionEnabled = true // 创建放大ImageView let enlargedImageView = UIImageView(image: originalImage) enlargedImageView.center = backgroundView.center enlargedImageView.contentMode = .scaleAspectFit enlargedImageView.isUserInteractionEnabled = true // 点击背景或图片都关闭 let closeTap = UITapGestureRecognizer(target: self, action: #selector(closeEnlargedImage)) backgroundView.addGestureRecognizer(closeTap) backgroundView.addSubview(enlargedImageView) UIApplication.shared.keyWindow?.addSubview(backgroundView) } @objc func closeEnlargedImage(sender: UITapGestureRecognizer) { sender.view?.removeFromSuperview() }
为什么iOS 11会出现这个问题?
iOS 11中导航控制器新增了UINavigationControllerPaletteClippingView,用来处理导航栏的动态过渡效果,它的视图层级默认会高于你直接添加到当前控制器视图的子视图,所以会拦截点击事件。
内容的提问来源于stack exchange,提问作者rharding
相关产品推荐
相关产品推荐

