UITableViewCell“完全”滑动,从右到左

时间:2017-05-01 16:12:53

标签: ios uitableview swipe

我有一个UITableView,当从右向左滑动时,单元格已经实现了两个自定义按钮(UITableViewRowAction编辑操作)。一切顺利。

我想在用户“一路”(也从右到左)滑动时触发其中一个按钮操作,类似于Mail.app。

代码是Swift 3,适用于iOS 9和10。

我有我认为足够的代码。

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    return .delete
 }

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    print("commit editingStyle")
}

commit editingStyle函数永远不会像我期望的那样触发。

我删除了editActionsForRowAt方法,想到也许我在定义自定义按钮时搞砸了一些东西。我现在看到默认的“删除”按钮,但commit editingStyle仍然不会触发。

对于它的价值,这是UIViewController(不是UITableViewController)中的UITableView,同时将.dataSource和.delegate设置为相关类。它也是一个NSFetchedResultsControllerDelegate。

3 个答案:

答案 0 :(得分:0)

UISwipeGestureRecognizer附加到表格本身,而不是附加到单个单元格。检测到滑动时,计算刷过哪个单元格,然后相应地调用滑动操作。

答案 1 :(得分:0)

添加:

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

答案 2 :(得分:0)

我想出了一个机制来做到这一点,我认为这不是太多的黑客 - 当然比我发现的其他解决方案更少。欢迎提出意见。

我的意图始终是尽可能多地使用标准功能。我正在做的是跟踪用户向左侧滑动单元主体的距离。当达到某个阈值时,我告诉UITableView执行从editActionsForRowAt为相关按钮调用的相同操作。

我使用-225作为移动单元格左侧的阈值。这可能不适用于所有实现(我可能会通过更多测试来修改自己)。在我的情况下,我有两个自定义动作,一个按钮有点广泛。

我真正添加的唯一内容是NSTimer,我使用.UITrackingRunLoopMode将其添加到主运行循环中。这具有在用户移动手指时(并且仅在何时)运行的益处。当计时器触发时,我检查单元格相对于主机tableView的位置。没有添加视图,没有添加手势识别器。

在自定义UITableViewCell中,我添加了这个:

var trackTimer:Timer? = nil
weak var tableView:StudentsLessonsViewController? = nil

override func awakeFromNib() {
    super.awakeFromNib()
    setupTimer()
}

override func prepareForReuse() {
    super.prepareForReuse()
    setupTimer()
}

func setupTimer() {
    self.trackTimer = Timer.init(timeInterval: 0.1, target: self, selector: #selector(performActionIfScrolledFarEnough), userInfo: nil, repeats: true)
    if let trackTimer = self.trackTimer {
        RunLoop.main.add(trackTimer, forMode: .UITrackingRunLoopMode)
    }
}

func performActionIfScrolledFarEnough() {
    let globalPoint = self.superview?.convert(self.frame.origin, to: self.tableView?.tableView)
    //print("globalPoint.x: \(String(describing: globalPoint?.x))")
    if let globalPoint = globalPoint {
        if globalPoint.x < CGFloat(-225) {
            //print ("Perform Action NOW!!!")
            trackTimer?.invalidate()
            if let tableView = self.tableView {
                tableView.primaryActionButtonPressed(cell: self)
            }
        }
    }
}

在UITableView的cellForRowAtIndexPath中,我添加了:

cell?.tableView = self

我已经在我的UITableView中使用了这个函数,当用户点击editActionsForRowAt中定义的一个按钮时,我正在调用它:

func tableView.primaryActionButtonPressed(cell:UITableViewCell)

在我的primaryActionButtonPressed函数中,我从tableView中删除了单元格(概念上就像删除一样)。可能不同的操作可能需要不同的实现细节。