Swift集合视图中UITapGestureRecognizer对Cell图片的异常问题咨询
问题解决方案
1. 点击新图自动移除已显示的放大图
在控制器中添加全局变量追踪当前显示的放大图,每次点击新图前先清理旧图:
var currentFullscreenImageView: UIImageView?
修改cellTappedMethod方法:
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){ // 移除已显示的放大图 currentFullscreenImageView?.removeFromSuperview() let imageView = sender.view as! UIImageView let newImageView = UIImageView(image: imageView.image) newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0) // 保存当前放大图引用 currentFullscreenImageView = newImageView UIView.animate(withDuration: 0.2) { [self] in newImageView.center = CGPoint(x: UIScreen.main.bounds.midX - 15, y: UIScreen.main.bounds.midY - 200) newImageView.backgroundColor = .clear newImageView.contentMode = .scaleAspectFit newImageView.isUserInteractionEnabled = true let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage)) newImageView.addGestureRecognizer(tap) self.view.addSubview(newImageView) } }
更新dismissFullscreenImage方法清空引用:
@objc func dismissFullscreenImage(sender: UITapGestureRecognizer) { UIView.animate(withDuration: 0.2) { sender.view?.removeFromSuperview() } currentFullscreenImageView = nil }
2. 点击放大图外部(CollectionView区域)touchesBegan未触发的原因及解决
原因
- UICollectionView自带手势识别器(如滑动、长按),会优先拦截触摸事件,导致控制器
touchesBegan无法响应。 - 原有
touchesBegan逻辑错误:创建空的UITapGestureRecognizer,其view始终为nil,无法执行移除操作。
解决方案
添加全屏透明遮罩视图,放在放大图下方处理外部点击:
- 添加遮罩变量:
var overlayView: UIView?
- 修改
cellTappedMethod添加遮罩:
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){ // 清理旧的放大图和遮罩 currentFullscreenImageView?.removeFromSuperview() overlayView?.removeFromSuperview() let imageView = sender.view as! UIImageView let newImageView = UIImageView(image: imageView.image) newImageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width * 0.7, height: 300.0) currentFullscreenImageView = newImageView // 创建全屏遮罩 overlayView = UIView(frame: UIScreen.main.bounds) overlayView?.backgroundColor = UIColor.black.withAlphaComponent(0.5) overlayView?.isUserInteractionEnabled = true let overlayTap = UITapGestureRecognizer(target: self, action: #selector(dismissAllFullscreenContent)) overlayView?.addGestureRecognizer(overlayTap) UIView.animate(withDuration: 0.2) { [self] in newImageView.center = CGPoint(x: UIScreen.main.bounds.midX - 15, y: UIScreen.main.bounds.midY - 200) newImageView.backgroundColor = .clear newImageView.contentMode = .scaleAspectFit newImageView.isUserInteractionEnabled = true let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage)) newImageView.addGestureRecognizer(tap) self.view.addSubview(overlayView!) self.view.addSubview(newImageView) } }
- 添加移除遮罩和放大图的方法:
@objc func dismissAllFullscreenContent() { UIView.animate(withDuration: 0.2) { self.currentFullscreenImageView?.removeFromSuperview() self.overlayView?.removeFromSuperview() } currentFullscreenImageView = nil overlayView = nil }
可直接删除原有touchesBegan方法,遮罩已处理外部点击逻辑。
3. 点击Cell图片时移除所有前景放大图
给所有放大图设置统一标签,点击时遍历移除:
- 定义常量标签:
let fullscreenImageTag = 1001
- 修改
cellTappedMethod给新图设置标签:
newImageView.tag = fullscreenImageTag
- 在点击Cell图片时先清理所有放大图:
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){ // 移除所有带指定标签的放大图 self.view.subviews.forEach { subview in if subview.tag == fullscreenImageTag { subview.removeFromSuperview() } } overlayView?.removeFromSuperview() // 后续创建新图的逻辑不变... }
也可通过数组管理所有放大图:
var fullscreenImageViews: [UIImageView] = []
添加新图时存入数组,点击时清空:
@objc func cellTappedMethod(_ sender: UITapGestureRecognizer){ fullscreenImageViews.forEach { $0.removeFromSuperview() } fullscreenImageViews.removeAll() overlayView?.removeFromSuperview() // 创建新图后加入数组 fullscreenImageViews.append(newImageView) // 后续逻辑... }
内容的提问来源于stack exchange,提问作者iOS work
相关产品推荐
相关产品推荐

