如何将 UITapGestureRecognizer 添加到 UICollectionViewCell 中的图像
Posted
技术标签:
【中文标题】如何将 UITapGestureRecognizer 添加到 UICollectionViewCell 中的图像【英文标题】:How to add UITapGestureRecognizer to an image within UICollectionViewCell 【发布时间】:2021-02-12 05:36:40 【问题描述】:我的每个单元格都包含一个 imageView。目标是拥有它,以便在任何时候点击或滑动单元格(或 imageView)时,图像都会随着相应的点击或滑动动画而变化。 (点击动画缩小后扩大,而滑动动画将imageView旋转180度)
起初我在我的收藏视图的didSelectItemAt
方法中设置了我的点击功能,并且效果很好。但是,当我尝试添加滑动功能时,我发现任何用户与单元格的交互都会触发相同的点击动画。
所以,现在我正在尝试在cellForItemAt
中设置点击功能。但是,由于某种原因没有调用分接选择器。任何想法为什么?
我正在使用 UICollectionViewController。 Xcode 12,快速 5。
编辑
按照@Sandeep Bhandari 的建议,我现在正在实现一个协议,以在单元格(对点击手势具有强引用)和 UICollectionViewController 之间进行通信。但是,仍然没有调用选择器。
GameTileCell
@objc protocol GameTileCellProtocol
func didTapImageView(for cell: GameTileCell)
class GameTileCell: UICollectionViewCell
// other properties
var gesture: UITapGestureRecognizer?
weak var delegate: GameTileCellProtocol?
override init(frame: CGRect)
super.init(frame: frame)
// call configure cell method
gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
gameTileImageView.isUserInteractionEnabled = true
gameTileImageView.addGestureRecognizer(gesture!)
// storyboard init
// configure cell method defined
@objc func handleTap(_ sender: UITapGestureRecognizer)
self.delegate?.didTapImageView(for: self)
print("handleTap")
UICollectionViewController
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GameTileCell.reuseID, for: indexPath) as! GameTileCell
setImageAndColor(for: cell)
cell.delegate = self
return cell
// other methods
extension GameTileCVC: GameTileCellProtocol
func didTapImageView(for cell: GameTileCell)
UIView.animate(withDuration: 0.4)
cell.gameTileImageView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
completion: (_ finished: Bool) in
UIView.animate(withDuration: 0.4)
self.setImageAndColor(for: cell)
cell.gameTileImageView.transform = CGAffineTransform.identity
print(#function)
【问题讨论】:
添加了新答案请检查 【参考方案1】:您正在cellForItemAt indexPath: IndexPath)
方法内创建一个轻击手势识别器,这意味着它是该方法内的一个局部变量。此手势识别器的范围仅在此函数cellForItemAt indexPath: IndexPath)
内,一旦控制离开函数的范围手势识别器将被释放,因此触摸将不起作用。
您需要保持对点击手势识别器的强引用,因此我建议将此点击手势识别器从您的 ViewController 移动到 GameTileCell
。
因此,将您的 GameTiteCell
实现更改为类似
class GameTileCell: UICollectionViewCell
let gesture: UITapGestureRecognizer
weak var delegate: GameTitleCellProtocol?
//other declarations of yours
override init(frame: CGRect)
super.init(frame: frame)
gameTileImageView.isUserInteractionEnabled = true
gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
self.gameTileImageView.addGestureRecognizer(gesture)
@objc func handleTap(_ sender: UITapGestureRecognizer)
self.delegate?.didTapImageView(for: self)
声明一个协议以在您的单元格和您的 ViewController 之间进行通信。让我们称之为
@objc protocol GameTitleCellProtocol
func didTapImageView(for cell: GameTileCell)
最后,让您的 ViewController 成为您的 GameTileCell
在cellForRowAtIndexPath
中的代表
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GameTileCell.reuseID, for: indexPath) as! GameTileCell
setImageAndBgColor(for: cell)
cell.delegate = self
return cell
最后让你的 ViewController 确认GameTitleCellProtocol
协议
extension YourViewController: GameTitleCellProtocol
func didTapImageView(for cell: GameTileCell)
UIView.animate(withDuration: 0.4)
cell.gameTileImageView.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
completion: (_ finished: Bool) in
UIView.animate(withDuration: 0.4)
self.setImageAndBgColor(for: cell)
cell.gameTileImageView.transform = CGAffineTransform.identity
【讨论】:
感谢您再次查看!我确实实施了您的建议,但仍然没有看到任何变化。我在didTapImageView
和handleTap
选择器中放置了打印语句,但都没有打印。应用不会崩溃,但点击单元格时不会发生任何事情。
@melh0n: 一个一个调试 1. 你在imageView上启用用户交互了吗?我已将其设置在 init 请检查是否触发了 init,是否执行了其中的语句 2.您的分接选择器是否被触发?在didTapImageView
中设置一个断点并检查控制是否到达那里? 3. 您是否将视图控制器设置为 cellForRowAtIndexPath 中的单元格委托。最后,当您说“点击单元格时没有任何反应”时,在 imageView 上添加了点击手势,我们仅调试 imageView 点击而不是单元格点击,如果单元格点击不工作,因为allowsSelection
存在
设置为 false 我在之前的回答中错误地提到了
我已经编辑了 OP 以包含您的建议作为实施。 1. 正在触发初始化并启用用户交互。 2.点击选择器没有被触发!控制未达到didTapImageView
3. VC 在cellForItemAt indexPath
中设置为单元格的代表,我想这就是您要说的(不是行)。
正确,点击手势已添加到 imageView。我的 imageView 固定在其单元格的边缘,因此当用户点击 imageView 时,他们实际上也在点击单元格......哦,allowsSelection
目前没有设置任何内容。【参考方案2】:
如果您想为您的单元格添加点击和滑动功能,您需要为每个单元格定义一个单独的手势识别器:
let tap = UITapGestureRecognizer(target: self, action:#selector(tapAction(_:)))
let swipe = UISwipeGestureRecognizer(target: self, action:#selector(swipeAction(_:)))
view.addGestureRecognizer(tap)
view.addGestureRecognizer(swipe)
为什么你的选择器动作没有被调用:你有没有在这一行设置断点?
if let indexPath = self.collectionView?.indexPathForItem(at: sender.location(in: self.collectionView))
我认为 if 可能不会变成积极的,因此你的行动什么也不做。
【讨论】:
抱歉延迟回复!控件甚至没有到达if let indexPath
处设置的断点。我想这再次证实了我没有调用处理程序的假设:\以上是关于如何将 UITapGestureRecognizer 添加到 UICollectionViewCell 中的图像的主要内容,如果未能解决你的问题,请参考以下文章