Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何向UICollectionViewCell中的图像添加UIAPTgestureRecognitor_Ios_Swift_Uigesturerecognizer_Uicollectionviewlayout_Uitapgesturerecognizer - Fatal编程技术网

Ios 如何向UICollectionViewCell中的图像添加UIAPTgestureRecognitor

Ios 如何向UICollectionViewCell中的图像添加UIAPTgestureRecognitor,ios,swift,uigesturerecognizer,uicollectionviewlayout,uitapgesturerecognizer,Ios,Swift,Uigesturerecognizer,Uicollectionviewlayout,Uitapgesturerecognizer,我的每个单元格都包含一个imageView。目标是使其在任何时候点击或滑动单元格(或imageView)时,图像都会随着相应的点击或滑动动画发生变化。(点击动画先收缩后扩展,而滑动动画将imageView旋转180度) 首先,我在集合视图的didSelectItemAt方法中设置了点击功能,效果很好。但是,当我尝试添加滑动功能时,我发现任何用户与单元格的交互都会触发相同的点击动画 因此,现在我正在尝试在cellForItemAt中设置tap功能。但是,由于某些原因,没有调用抽头选择器。你知道为什

我的每个单元格都包含一个imageView。目标是使其在任何时候点击或滑动单元格(或imageView)时,图像都会随着相应的点击或滑动动画发生变化。(点击动画先收缩后扩展,而滑动动画将imageView旋转180度)

首先,我在集合视图的
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.点击选择器未被触发!控件未到达didTapImageView
3。VC在
cellForItemAt indexPath
中被设置为单元格的委托,我想这是您的意思(不是行)。感谢您再次查看!我确实执行了你的建议,但仍然没有看到任何变化。我在
didTapImageView
handleTap
选择器中放置了打印语句,但都没有打印。应用程序不会崩溃,但当点击单元格时不会发生任何事情。@melh0n:逐个调试1。是否已在imageView上启用用户交互?我已经在init中设置了它,请检查init是否被触发,它里面的语句是否被执行。您的点击选择器是否被触发?在
didTapImageView
中放置一个断点,并检查控件是否到达该断点?3.是否已在cellForRowAtIndexPath中将视图控制器设置为单元格的代理。最后当你说“不”的时候