0

I need help with an issue in Collection Views. In my collectionView I am using UILongPressGestureRecognizer to start CABasicAnimation in the items (images), but when I remove an item and reload the collectionView the CABasicAnimation is interrupeted. How can I prevent the animation stop? I need the animation continues until the user decide to stop.

Here is some information about my collectionView:

class SentMemesCollectionVC: UICollectionViewController {

//MARK: - PROPERTIES

var memes: [Meme]! {
    return Meme.accessMemes().memes
}

//MARK: - LIFE CYCLE

override func viewDidLoad() {
    super.viewDidLoad()

    let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap(_:)))
    self.collectionView.addGestureRecognizer(longPressGesture)
}

@objc func longTap(_ gesture: UILongPressGestureRecognizer) {

    switch gesture.state {
    case .began:
        print("LongPress begin")
        guard let selectedIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {return}
        collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
        setEditing(true, animated: true)

    default:
        collectionView.cancelInteractiveMovement()
    }

}

// MARK: - COLLECTIONVIEW DATA SOURCE


//Defini o número de itens em cada seção
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
   return memes.count
}


override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "gridCell", for: indexPath) as! GridMemeCell
    let meme = memes[indexPath.row]
    cell.prepareGridCell(with: meme)
    cell.delegate = self
    return cell
}

// MARK: - COLLECTIONVIEW DELEGATE
/*
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let memeDetail = storyboard?.instantiateViewController(withIdentifier: "DetailVC") as! MemeDetailVC
    let meme = memes[indexPath.row]
    memeDetail.memeSelected = meme
    Feedback.share.hapticFeedback()

    navigationController?.pushViewController(memeDetail, animated: true)
}
*/
// MARK: - DELETE ITEMS IN COLLECTVIEW


override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)
    Feedback.share.hapticFeedback()

    if let indexPaths = collectionView?.indexPathsForVisibleItems {
        for indexPath in indexPaths {
            if let cell = collectionView?.cellForItem(at: indexPath) as? GridMemeCell {

                if editing {
                    cell.isEditing = editing
                    cell.startAnimate()
                    doneBarButtonItem()

                } else {
                    cell.isEditing = editing
                    cell.stopAnimate()
                    addBarButtonItem()
                }
            }
        }
    }
}

}

Here is my CollectionViewCell

class GridMemeCell: UICollectionViewCell {

//MARK: - OUTLETS

@IBOutlet weak var ivImage: UIImageView!
@IBOutlet weak var deleteMeme: UIVisualEffectView!

//MARK: - PROPERTIES

weak var delegate: GridMemeCellDelegate?

var isAnimate: Bool! = true

//MARK: - METHODS AND COMPUTED PROPERTIES


func prepareGridCell(with meme: Meme) {
    ivImage.image = meme.memeImage

    deleteMeme.layer.cornerRadius = deleteMeme.bounds.width / 2.0
    deleteMeme.layer.masksToBounds = true
    deleteMeme.isHidden = !isEditing
    deleteMeme.contentView.backgroundColor = Theme.current.subViewColor

}

func startAnimate() {
    let shakeAnimation = CABasicAnimation(keyPath: "transform.rotation")
    shakeAnimation.duration = 0.05
    shakeAnimation.repeatCount = 4
    shakeAnimation.autoreverses = true
    shakeAnimation.duration = 0.2
    shakeAnimation.repeatCount = 99999

    let startAngle: Float = (-2) * 3.14159 / 180
    let stopAngle = -startAngle

    shakeAnimation.fromValue = NSNumber(value: startAngle)
    shakeAnimation.toValue = NSNumber(value: 3 * stopAngle)
    shakeAnimation.autoreverses = true
    shakeAnimation.timeOffset = 290 * drand48()

    let layer: CALayer = self.layer
    layer.add(shakeAnimation, forKey: "animate")
    self.deleteMeme.isHidden = false
    isAnimate = true

}

func stopAnimate() {
    let layer: CALayer = self.layer
    layer.removeAnimation(forKey: "animate")
    self.deleteMeme.isHidden = true
    isAnimate = false

}


var isEditing: Bool = false {
    didSet {
        deleteMeme.isHidden = !isEditing

    }
}

@IBAction func btDeleteMeme(_ sender: Any) {
    Feedback.share.hapticFeedback()
    delegate?.deleteCell(cell: self)

}

}

And here is my Protocol Delegate Cell:

protocol GridMemeCellDelegate: class {
func deleteCell(cell: GridMemeCell)

}

And here is my extension CollectionView - Delegate.

extension SentMemesCollectionVC: GridMemeCellDelegate {
func deleteCell(cell: GridMemeCell) {
    if let indexPath = collectionView.indexPath(for: cell) {

        //Apaga o Meme do Array
        Meme.accessMemes().memes.remove(at: indexPath.item)
        collectionView.reloadData()

    }
}

}

Afonso
  • 87
  • 2
  • 9
  • You can’t prevent it from stopping. It is up to you to start the animation again after the reload. – matt Feb 16 '19 at 12:41
  • Do you have any suggestion how the best way to do it with an animation auto reload? – Afonso Feb 16 '19 at 12:53
  • I don't know what you mean. The animation cannot magically survive a reload, so it's up to you to start it again after the reload if that's what you want. Your code started the animation in the first place, so you know at all times which cells are animating. After a reload, if you had cells that were animating before the reload, animate them again. – matt Feb 16 '19 at 15:29
  • When I press the icons in iPhone they start the shake animation and I can delete more than one of them without the animation stops. I'd like the same behavior in my app. How can I do it? – Afonso Feb 16 '19 at 15:59

0 Answers0