iOS Swift: удалите TableViewCell с помощью Swipe, как карты Google Now
Я должен реализовать Swipe, чтобы удалить ячейку таблицы из таблицы, как карты Google Now. Я пытался эту логику с помощью сенсорных событий. Но не получил это как Google Now. И это не так гладко. К вашему сведению, я поместил следующий код в свою ячейку
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;
}
}
Здесь сенсорный конец события срабатывает чаще. Я думаю, вот почему гладкости нет. Пожалуйста, предоставьте мне лучший способ для удаления салфетки из таблицы, как в Google Now Cards.
Заранее спасибо.
1 ответ
Хорошо, вчера я ответил на аналогичный вопрос о пользовательском пролистывании для отображения кнопок, ваш вопрос будет использовать точно такую же функциональность, за исключением того, что при панорамировании на определенное расстояние он будет "удаляться", поэтому...
Здесь у нас есть настройка жеста панорамирования, чтобы показать кнопки
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 для обновления моделей.