-1

I have to implement Swipe to remove tableview cell from tableview like Google Now cards. I tried to that logic through touch events. But didnt get that like Google Now. And it is not so smooth. FYI, I have put the following code in my custom tableviewcell

 func getGestureDirectionWithTouch(touch:UITouch) -> SwipeDirection{

        let gestureEndPoint = touch.location(in: self)
        let dx = fabs((self.gestureStartPoint?.x)! - gestureEndPoint.x);
        let dy = -1 * (gestureEndPoint.y - (self.gestureStartPoint?.y)!);

        if(dx > 20) {
            // left/right
            return .Right
        }

        if(dy < 0) {
            // down
            return .Down
        }else if(dy > 0) {
            // up
            return .Up;
        }

        return .none
    }



    // MARK: - Touch Events

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(#function)
        super.touchesBegan(touches, with: event)
        if let touch = touches.first {

            self.gestureStartPoint = touch.location(in: self)
        }

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(#function)
        if let touch = touches.first {

            //gets gesture direction
            self.gestureDirection = self.getGestureDirectionWithTouch(touch: touch)

            //send event
            if (self.gestureDirection == .Left || self.gestureDirection == .Right) {
                //exit if view is self or if view can't swipe
               // if self.gestureView == self || !self.canSwipe(view: gestureView!) {
                 //   return;
                //}

                //swipe card
                let gestureEndPoint = touch.location(in: self)
                self.frame = (self.frame).offsetBy(dx: (gestureEndPoint.x - (self.gestureStartPoint?.x)!),
                                                                              dy: (0))
                if ((self.alpha) > CGFloat(0.4)) {
                    self.alpha=(self.alpha)-0.01
                }
            }
        }
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print(#function)


            //we are swiping a card
            let x = self.frame.origin.x

            if fabs(Double(x)) > Double(self.frame.size.width/2){

                //card will be deleted when x is greater than half width view

            }else{
                //card will be positioned at the orginila position
                self.center = self.cellCenter!
                self.alpha=1.0;
            }     

    }

Here touch end event triggered more oftenly. I think thats why the smoothness is not there. Please provide me the best way to achieve the swipe to remove tableviewcell from tableview as like Google Now Cards.

Thanks in advance.

Sridhar
  • 2,228
  • 10
  • 48
  • 79
  • 1
    There is function in table view cell to delete on swipe. This link might help you : http://stackoverflow.com/questions/3309484/uitableviewcell-show-delete-button-on-swipe. You do not need to play with touch delegates. Hope this helps you out! – Pallavi Srikhakollu Apr 27 '17 at 11:30
  • @PallaviSrikhakollu , Will it look like Google Now app? because I dont need to show delete button on swiping the cell. – Sridhar Apr 27 '17 at 13:22

1 Answers1

0

OK, I answered a similar question yesterday on custom swipe to show buttons, your question would use the exact same functionality except when you pan a certain distance it would 'swipe to delete', so...

Here we have setting up a pan gesture to show buttons

var savedX = 0 as CGFloat
var buttonWidth = 60 as CGFloat
var open = false

func panGestureHandler(gesture: UIPanGestureRecognizer) {
if gesture.state == .Changed {
    let translation = gesture.translationInView(tagView)

    let difference = -translation.x

    if difference > 0 && !allowScrollRight {
        return
    }

    let newConstant = savedX + difference

    tagViewCenterXConstraint.constant = newConstant

    let alpha = abs(tagViewCenterXConstraint.constant) / buttonWidth

    deleteButton.alpha = min(alpha, 1)
    followButton.alpha = min(alpha, 1)

    if let action = swipe {
        action(self)
    }
}

if gesture.state == .Ended {
    let translation = gesture.translationInView(self)

    let trans = fabs(translation.x)

    open = !open && trans > buttonWidth

    if open {
        if(translation.x > 0){
            resetRight(true)
        } else {
            if allowScrollRight {
                resetLeft(true)
            }
        }
    } else {
        resetView(true){

        }
    }
}
}
 func resetLeft (animated : Bool) {
        tagViewCenterXConstraint.constant = self.buttonWidth
        savedX = self.buttonWidth
if animated {
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: [UIViewAnimationOptions.CurveEaseIn, UIViewAnimationOptions.BeginFromCurrentState], animations: { () -> Void in
        self.tagView.layoutIfNeeded()
        self.leftView.layoutIfNeeded()
        self.rightView.layoutIfNeeded()

        }, completion: { (finished) -> Void in
    })
}
}
func resetRight (animated : Bool) {
    tagViewCenterXConstraint.constant = -self.buttonWidth
    savedX = -self.buttonWidth

if animated {
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: [UIViewAnimationOptions.CurveEaseIn, UIViewAnimationOptions.BeginFromCurrentState], animations: { () -> Void in
        self.tagView.layoutIfNeeded()
        self.leftView.layoutIfNeeded()
        self.rightView.layoutIfNeeded()

        }, completion: { (finished) -> Void in
    })
}
}
func resetView (animated : Bool, completion: () -> Void ) {
    tagViewCenterXConstraint.constant = 0

savedX = 0
open = false

if animated {
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: [UIViewAnimationOptions.CurveEaseIn, UIViewAnimationOptions.BeginFromCurrentState], animations: { () -> Void in
        self.tagView.layoutIfNeeded()
        self.leftView.layoutIfNeeded()
        self.rightView.layoutIfNeeded()

        }, completion: { (finished) -> Void in
            completion()
    })
} else {
    completion()
    }
}

I know its a lot of code, but that is what it does, now, what you need to do is check the velocity and distance of the translation on gesture state changed, this when passed a certain threshold would call your swipe to delete function, which would then animate the panned view off the screen and call a delegate, passing the cell to the VC to call deleteCellAtIndexPath: which would delete the cell, also removing the model from your view and any relevant API calls to update models.

Sean Lintern
  • 3,103
  • 22
  • 28