iOS Swift:通过Swipe删除TableViewCell,就像Google Now Cards一样

时间:2017-04-27 11:24:51

标签: ios swift google-now

我必须实施Swipe以从Google View卡中移除tableview单元格。我通过触摸事件尝试了这种逻辑。但就像Google Now一样。它不是那么顺利。 仅供参考,我已将以下代码放入自定义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;
            }     

    }

此处触摸结束事件更频繁地触发。我认为这就是为什么没有光滑度。请向我提供实现滑动以从tableview中移除tableviewcell的最佳方式,如Google即时卡。

提前致谢。

1 个答案:

答案 0 :(得分:0)

好的,我昨天在自定义滑动显示按钮时回答了类似的问题,你的问题将使用完全相同的功能,除非你平移一定距离它会滑动删除&#39;,所以......

这里我们设置了一个平移手势来显示按钮

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()
    }
}

我知道很多代码,但这就是它的功能,现在,您需要做的是检查手势状态转换时的转换速度和距离,当超过某个阈值时,会调用您的滑动删除函数,然后将屏幕上的平移视图设置为动画并调用委托,将单元格传递给VC以调用deleteCellAtIndexPath:这将删除单元格,同时从视图中删除模型以及更新模型的任何相关API调用。