ios - UITableView tableView(_ :didEndEditingRowAt:) not called if rapidly tapping during swipe

标签 ios iphone swift uitableview

我有一个 UITableVieweditAction向左滑动即可访问。

似乎有一个内置的 UITableView功能,如果您滑动单元格以显示编辑操作,然后点击 tableView 中的任意位置,操作将自动滑动关闭,didEndEditingRowAt被调用以通知代理编辑已结束。

但是,我看到的问题是,有时,如果您向左滑动,然后在滑动后很快(当只有一小部分编辑操作可见并且动画正在进行时),您可以点击任意位置在屏幕上的其他地方,编辑操作已关闭,但 didEndEditingRowAt不叫!

因此,使用以下代码,我们最终将 tableView 置于编辑模式,但没有 View 被滑动打开,最后一行打印为 Will Edit ,确认 didEndEditingRowAt从未被调用。

  class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

  let tableView = UITableView()

  override func viewDidLoad() {
    super.viewDidLoad()

    view = tableView
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "foo")
    tableView.delegate = self
    tableView.dataSource = self
    tableView.allowsSelectionDuringEditing = false
  }

  func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let deleteAction = UITableViewRowAction(style: .normal, title: " Remove") {(_, indexPath) in print("OK") }
    return [deleteAction]
  }

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}

  func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {}

  func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    return indexPath
  }


  func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
    print("Will edit")
  }

  func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) {
    print("Did end edit")
  }

  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 80
  }

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

  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    return tableView.dequeueReusableCell(withIdentifier: "foo") ?? UITableViewCell()
  }

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10
  }
}

现在,这只是偶尔发生,而且很难把握好时机,但它绝对可以重现。

这是整个演示的链接:https://github.com/gregkerzhner/SwipeBugDemo

我是不是做错了或预料到了什么问题?在我的真实项目中,我有代码淡化其他单元格以专注于当前正在编辑的单元格,但我最终处于其他单元格淡化的糟糕状态,但聚焦的单元格没有打开任何编辑操作。

最佳答案

这绝对是 UITableView 中的一个错误,即使滑动反弹回来(例如,如果你滑动它只是一点点),它仍然处于“编辑”状态。

好消息是您可以使用 UITableViewCell 的一些方法来找到解决方法。 UITableViewCell 有相应的方法来通知与 Action 相关的状态变化:

func willTransition(to state: UITableViewCellStateMask)
func didTransition(to state: UITableViewCellStateMask)
func setEditing(_ editing: Bool, animated: Bool)
var showingDeleteConfirmation: Bool { get }

过渡方法在过渡(和动画)开始和结束时被调用。当你滑动时,willTransitiondidTransition 将被调用(状态为 .showingDeleteConfirmationMask),showingDeleteConfirmation 将被 setEditing 也被调用为 true

虽然这仍然存在问题(除非您真正揭开按钮,否则单元格不应该成功地成为编辑状态),didTransition 是一个回调,您有机会检查操作 View 是否确实可见。我不认为有任何可靠的方法可以做到这一点,但也许只是检查单元格的 contentView 占据了它的大部分边界就足够了。

关于ios - UITableView tableView(_ :didEndEditingRowAt:) not called if rapidly tapping during swipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44125202/

相关文章:

iphone - 仅适用于 iphone 的单点触控应用程序分发

iphone - Xcode 错误地声称 CFBundleExecutable 为 (null)

iOS:在扩展中从 NSNotificationCenter 返回值(swift)

ios - 基类的 loadNibNamed 覆盖子类的实例

ios - uicollectionviewcell swift ios 中的自定义复选框

swift - “ fatal error :在展开可选值时意外发现nil”是什么意思?

ios - 以编程方式翻页,指标不变

ios - fatal error : unexpectedly found nil while unwrapping an Optional value (lldb)

ios - 将数据(标签)从 TableViewCell 传递到另一个 ViewController

iphone - 在 Objective C 中使用 #define 或 extern NSString *const 哪个更好