滑动删除 UITableView (iOS) 中的整个部分

Posted

技术标签:

【中文标题】滑动删除 UITableView (iOS) 中的整个部分【英文标题】:Swipe to delete entire section in UITableView (iOS) 【发布时间】:2017-10-13 22:58:34 【问题描述】:

过去我使用MGSwipeTableCell 滑动以消除单元格取得了很大的成功,但我当前的任务调用以相同的行为滑动整个部分。

我目前在 UITableView 中有一个滑动手势识别器,当触发滑动手势时,我计算收到触摸的部分,并删除填充该部分的对象(在核心数据中),然后调用删除动画:

//Delete objects that populate table datasource 
for notification in notifications 
    notificationObject.deleted = true


DataBaseManager.sharedInstance.save()

let array = indexPathsToDelete
let indexSet = NSMutableIndexSet()
array.forEach(indexSet.add)

//Delete section with animation            
self.notificationsTableView.deleteSections(indexSet as IndexSet, with: .left)

这可行,但并不理想。理想情况下,我们希望用手指拖动整个部分(当在某个点释放时,它会离开屏幕),类似于 MGSwipeTableCell。解决这个问题的最佳方法是什么?是否有另一个库允许滑动删除部分(我找不到)?或者这是我必须自己创造的东西。

【问题讨论】:

UITableViews 上的滑动手势通常很脏,因为UITableViews 不仅会对滑动手势做出反应,而且它们的单元格也会做出反应。这里有一个想法,而不是打算在部分中的单元格上滑动来启动滑动,为什么不为该部分创建一个自定义标题单元格。因此,标题视图将包含其自己的滑动手势(或按钮)以显示“删除”按钮。当在标题中按下该按钮时,使用.deleteSections(indexSet as IndexSet, with: .left) 方法删除整个部分。 这是个好主意,但问题不在于滑动手势;问题是如果你明白我的意思,整个部分及其嵌套表需要随着手指的触摸一起拖动 【参考方案1】:

我没有对此进行测试,但想法如下。查看 (self.header) 并使用 touchesBegan... 方法检测用户将手指放在屏幕上。然后,用touchesMoved... 方法跟随手指,计算上一个偏移量和下一个偏移量的差值。它应该增长 1(或更多),具体取决于用户移动手指的速度。使用该值减去单元格的contentView 中的origin.x

var header: UIView!
var tableView:UITableView!
var offset:CGFloat = 0

override public func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    // Touches Began. Disable user activity on UITableView
    if let touch = touches.first 
        // Get the point where the touch started
        let point = touch.location(in: self.header)
        offset = point.x
    


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

        // Get the point where the touch is moving in header
        let point = touch.location(in: self.header)

        // Calculate the movement of finger
        let x:CGFloat = offset - point.x
        if x > 0 
            // Move cells by offset
            moveCellsBy(x: x)
        

        // Set new offset
        offset = point.x
    


override public func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
    // Reset offset when user lifts finter
    offset = 0


func moveCellsBy(x: CGFloat) 
    // Move each visible cell with the offset
    for cell in self.tableView.visibleCells 
        // Place in animation block for smoothness
        UIView.animate(withDuration: 0.05, animations: 
            cell.contentView.frame = CGRect(x: cell.contentView.frame.origin.x - x, y: cell.contentView.frame.origin.y, width: cell.contentView.frame.size.width, height: cell.contentView.frame.size.height)
        )
    

【讨论】:

感谢布兰登,在阅读您的答案之前,我实际上打算这样做。只是希望那里已经有一个图书馆可以做到这一点。 不用担心 ;)。也许你可以做一个这样做的小图书馆? 它肯定在议程中,不应该很困难:D【参考方案2】:

Brandon 的回答是正确的,但是,INSPullToRefresh 库在使用触摸开始和其他触摸委托方法时存在问题。

我要做的是实现一个 UIPanGestureRecognizer 并在触发该手势识别器事件时跟踪触摸

【讨论】:

以上是关于滑动删除 UITableView (iOS) 中的整个部分的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 iPad:UIPageViewController 中的 UITableView 滑动删除(手势识别器冲突)

在 iphone sdk 中一起滑动以删除和移动 UItableView 选项中的单元格

UITableView 滑动删除在 iOS8 上无法正常工作

UITableView滑动删除iOS上的手势冲突

在 Xamarin IOS 的 UITableview 中更改滑动以删除按钮高度

iOS 7 UITableView 问题 - 当我们已经有一个单元格时尝试设置滑动以删除单元格