Ios 如何向UICollectionViewCell中的图像添加UIAPTgestureRecognitor
我的每个单元格都包含一个imageView。目标是使其在任何时候点击或滑动单元格(或imageView)时,图像都会随着相应的点击或滑动动画发生变化。(点击动画先收缩后扩展,而滑动动画将imageView旋转180度) 首先,我在集合视图的Ios 如何向UICollectionViewCell中的图像添加UIAPTgestureRecognitor,ios,swift,uigesturerecognizer,uicollectionviewlayout,uitapgesturerecognizer,Ios,Swift,Uigesturerecognizer,Uicollectionviewlayout,Uitapgesturerecognizer,我的每个单元格都包含一个imageView。目标是使其在任何时候点击或滑动单元格(或imageView)时,图像都会随着相应的点击或滑动动画发生变化。(点击动画先收缩后扩展,而滑动动画将imageView旋转180度) 首先,我在集合视图的didSelectItemAt方法中设置了点击功能,效果很好。但是,当我尝试添加滑动功能时,我发现任何用户与单元格的交互都会触发相同的点击动画 因此,现在我正在尝试在cellForItemAt中设置tap功能。但是,由于某些原因,没有调用抽头选择器。你知道为什
didSelectItemAt
方法中设置了点击功能,效果很好。但是,当我尝试添加滑动功能时,我发现任何用户与单元格的交互都会触发相同的点击动画
因此,现在我正在尝试在cellForItemAt
中设置tap功能。但是,由于某些原因,没有调用抽头选择器。你知道为什么吗
我正在使用UICollectionViewController。代码12,swift 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)
}
}您正在
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成为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确认到GameTileCellProtocol
协议
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
}
}
}
}
您正在
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成为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确认到GameTileCellProtocol
协议
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
}
}
}
}
如果要向单元格中添加点击和滑动功能,则需要为每个单元格定义一个单独的手势识别器:
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可能不会产生积极的效果,从而使您的操作不做任何事情。如果您想在单元格中添加点击和滑动功能,您需要为每个单元格定义一个单独的手势识别器:
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可能不会产生积极效果,因此您的操作将不做任何事情。添加了一个新答案请检查添加了一个新答案请检查谢谢您再次查看!我确实执行了你的建议,但仍然没有看到任何变化。我在
didTapImageView
和handleTap
选择器中放置了打印语句,但都没有打印。应用程序不会崩溃,但当点击单元格时不会发生任何事情。@melh0n:逐个调试1。是否已在imageView上启用用户交互?我已经在init中设置了它,请检查init是否被触发,它里面的语句是否被执行。您的点击选择器是否被触发?在didTapImageView
中放置一个断点,并检查控件是否到达该断点?3.是否已在cellForRowAtIndexPath中将视图控制器设置为单元格的代理。最后,当您在imageView上添加“点击单元格时不会发生任何事情”点击手势时,我们只调试imageView点击,而不调试单元格点击,如果单元格点击因AllowSelection
设置为false而不工作,我在前面错误地提到了这一点answer@melh0n:嘿,你是德格吗?它起作用了吗?我已经编辑了OP,将您的建议包括在内。1.正在触发初始化并启用用户交互。2.点击选择器未被触发!控件未到达didTapImageView3。VC在cellForItemAt indexPath
中被设置为单元格的委托,我想这是您的意思(不是行)。感谢您再次查看!我确实执行了你的建议,但仍然没有看到任何变化。我在didTapImageView
和handleTap
选择器中放置了打印语句,但都没有打印。应用程序不会崩溃,但当点击单元格时不会发生任何事情。@melh0n:逐个调试1。是否已在imageView上启用用户交互?我已经在init中设置了它,请检查init是否被触发,它里面的语句是否被执行。您的点击选择器是否被触发?在didTapImageView
中放置一个断点,并检查控件是否到达该断点?3.是否已在cellForRowAtIndexPath中将视图控制器设置为单元格的代理。最后当你说“不”的时候