如何解决如何将 UITapGestureRecognizer 添加到 UICollectionViewCell 中的图像
我的每个单元格都包含一个 imageView。目标是让它在任何时候点击或滑动单元格(或 imageView)时,图像都会随着相应的点击或滑动动画而改变。 (tap 动画先缩小再扩大,而滑动动画将 imageView 旋转 180 度)
起初,我在集合视图的 body: _currentPosition == null
? Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,children: [
SizedBox(
height: 20.0,width: 20.0,child: CircularProgressIndicator(),),SizedBox(
width: 10.0,Text("Getting your location..."),],)
: Column(
...
方法中设置了点按功能,并且效果很好。但是,当我尝试添加滑动功能时,我发现任何用户与单元格的交互都会触发相同的点击动画。
所以,现在我正在尝试在 didSelectItemAt
中设置点击功能。但是,由于某种原因没有调用抽头选择器。任何想法为什么?
我正在使用 UICollectionViewController。 Xcode 12,快速 5。
编辑
按照@Sandeep Bhandari 的建议,我现在正在实施一个协议,以便在单元格(对点击手势具有强引用)和 UICollectionViewController 之间进行通信。但是,仍然没有调用选择器。
GameTileCell
cellForItemAt
UICollectionViewController
@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")
}
}
}
解决方法
您正在 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
}
}
}
}
,
如果您想为单元格添加点击和滑动功能,您需要为每个单元格定义一个单独的手势识别器:
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 可能不会变成积极的,因此你什么都不做就离开了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。