Search code examples
iosswiftuipangesturerecognizeruiswipegesturerecognizer

UISwipeGestureRecognizer animation


I'm trying to implement an UISwipeGestureRecognizer in my collectionViewCell, so when you swipe to the left, the cell disappear. What i'm trying to implement (i can't find a way to do it) is to animate the swipe, so when i swipe the cell to the left, it disappears with a fade effect. This is the code i have inside the method cellForItemAtindexPath

let cSelector = #selector(reset(sender:))
    let UpSwipe = UISwipeGestureRecognizer(target: self, action: cSelector)
    UpSwipe.direction = UISwipeGestureRecognizerDirection.left
    cell.addGestureRecognizer(UpSwipe)

The method

 func reset(sender: UISwipeGestureRecognizer) {

    let cell = sender.view as! UICollectionViewCell
    let i = self.collectionView?.indexPath(for: cell)!.item


    self.messages.remove(at: i!)
    self.collectionView?.reloadData()

}

Thanks!!!

EDIT: I think i found an easiest way to do it, but i'm having some troubles. I tried implementing a UIPanGestureRecognizer in the cell. This is how it looks like...

cellForItemAt

let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gestureRecognizer:)))
    cell.addGestureRecognizer(gestureRecognizer)

The method

func handlePan(gestureRecognizer: UIPanGestureRecognizer) {
    if gestureRecognizer.state == .began {
        // When the drag is first recognized, you can get the starting coordinates here

    }

    if gestureRecognizer.state == .changed {
        let translation = gestureRecognizer.translation(in: self.view)
        // Translation has both .x and .y values

        if translation.x == translation.x - 100 {
            //Method i putted before
            reset(sender: gestureRecognizer)
        }

        //print(translation.x, translation.y)
    }
}

I'm trying to locate the coordinates of the cell, so when it's in a point at the left of the cell, the cell stars some kind of fade animation, and then disappear.

Any help??? Thanks!!!


Solution

  • So i tried this code, and it works fine for me!

    func setupView(){
        // Setting up swipe gesture recognizers
        let swipeUp : UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(userDidSwipeUp(_:)))
        swipeUp.direction = .left
    
        collectionView?.addGestureRecognizer(swipeUp)
    
        //let swipeDown : UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(userDidSwipeDown))
        //swipeDown.direction = .right
    
        //collectionView?.addGestureRecognizer(swipeDown)
    }
    
    
    func getCellAtPoint(_ point: CGPoint) -> ChatMessageCell? {
        // Function for getting item at point. Note optionals as it could be nil
        let indexPath = collectionView?.indexPathForItem(at: point)
        var cell : ChatMessageCell?
    
        if indexPath != nil {
            cell = collectionView?.cellForItem(at: indexPath!) as? ChatMessageCell
        } else {
            cell = nil
        }
    
        return cell
    }
    
    func userDidSwipeUp(_ gesture : UISwipeGestureRecognizer) {
    
        let point = gesture.location(in: collectionView)  //collectionview
        let duration = animationDuration()                //0.5
    
        if(cell == nil){
            cell = getCellAtPoint(point)
    
            UIView.animate(withDuration: duration, animations: {
                //self.activeCell.myCellView.transform = CGAffineTransform(translationX: 0, y: -self.activeCell.frame.height)
                self.cell.celdaNormal.transform = CGAffineTransform(translationX: -self.cell.frame.width , y: 0)
    
            })
    
        }  else {
            // Getting the cell at the point
            let cell = getCellAtPoint(point)
    
            // If the cell is the previously swiped cell, or nothing assume its the previously one.
            if cell == nil || cell == cell {
                // To target the cell after that animation I test if the point of the swiping exists inside the now twice as tall cell frame
                let cellFrame = cell?.frame
    
                var rect = CGRect()
    
                if cell != nil {
                    rect = CGRect(x: (cellFrame?.origin.x)! - (cellFrame?.width)!, y: (cellFrame?.origin.y)!, width: (cellFrame?.width)!*2, height: (cellFrame?.height)!)
                }
    
                if rect.contains(point) {
                    // If swipe point is in the cell delete it
    
                    let indexPath = collectionView?.indexPath(for: cell!)
                    messages.remove(at: indexPath!.row)
                    collectionView?.deleteItems(at: [indexPath!])
    
                    if messages.count == 0 {
                        reusableView.etiqueta.isHidden = true
                    }
                }
                // If another cell is swiped
            }
    }
    
    func animationDuration() -> Double {
        return 0.5
    }
    

    All you have to do, is call the setupView() in viewDidLoad, and that's it! I have to mention that i modified the code from this question... Swipe to delete on CollectionView