在UITableViewCell上滑动时如何配置阈值/距离

时间:2018-11-12 15:23:51

标签: ios swift uitableview

我有可滑动查看的表格单元格。目的是让用户完全向左或向右滑动行(完全滑出),然后从表中删除滑动行(例如Gmail收件箱的工作方式)。一切正常,但我有一个问题。

func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let swipeRightAction = UIContextualAction(style: .destructive, title:  "", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        let item = self.myItems[indexPath.row]
        self.swipeRight(item) //do something
        self.myItems.remove(at: indexPath.row)
        success(true)
    })

    return UISwipeActionsConfiguration(actions: [swipeRightAction])
 }

我如何设置阈值/距离(在执行操作之前用户必须滑动多少)?当前,用户必须在行被刷除之前将其扫过一半。我可以更改这一点,以便用户只需要轻扫一下(例如20%的方式)即可滑出该行吗?

1 个答案:

答案 0 :(得分:3)

没有直接的配置方法。

解决方案

但是您可以自己构建它:

  • 将UIPanGestureRecognizer添加到表格中
  • 允许同时识别手势
  • 滑动结束后检查方向并计算出翻译的百分比
  • 确定受影响的表行
  • 删除

代码

将单元格向左滑动20%,导致删除一行,在代码中将如下所示:

class ViewController: UITableViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        let swipeGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(onSwiped(_:)))
        swipeGestureRecognizer.delegate = self
        self.tableView.addGestureRecognizer(swipeGestureRecognizer)
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }

    @objc private func onSwiped(_ gestureRecognizer: UIPanGestureRecognizer) {
        if gestureRecognizer.state == .ended {
            let translation = gestureRecognizer.translation(in: self.view)
            guard translation.x < 0 else { return }
            let width = self.tableView.bounds.width
            let percentage = -translation.x / width
            print("swiped left percentage:\(percentage)")
            if percentage > 0.2 {
                let location = gestureRecognizer.location(in: self.tableView)
                if let indexPath = self.tableView.indexPathForRow(at: location) {
                    print("delete row: \(indexPath.row)")
                    self.dataSource.remove(at: indexPath.row)
                    self.tableView.reloadData()
                }
            }
        }
    }

演示

swipe 20% to delete row