我有一个UITableView
,editAction
可通过向左滑动访问。
似乎有一个内置的UITableView
功能,如果您滑动单元格以显示编辑操作,然后点击tableView中的任意位置,操作将自动滑动关闭,{{1}调用}来通知代理编辑结束。
然而,我看到的问题是,有时候,如果你向左滑动然后在滑动后很快(当只有一小部分编辑动作可见且动画正在进行时),你可以点击任何地方否则屏幕上的编辑操作已关闭但didEndEditingRowAt
未被调用!
因此,使用以下代码,我们最终将tableView置于编辑模式,但没有打开视图,最后一行打印为didEndEditingRowAt
,确认从未调用过Will Edit
。
didEndEditingRowAt
现在,这种情况有时只会发生,并且有点难以确定正确的时机,但它绝对可以重现。
以下是整个演示的链接:https://github.com/gregkerzhner/SwipeBugDemo
我在这里做错了什么?在我的真实项目中,我的代码会淡化其他单元格以关注当前正在编辑的单元格,并且最终处于其他单元格褪色的错误状态,但是聚焦单元格没有打开任何编辑操作。 / p>
答案 0 :(得分:2)
这绝对是UITableView中的一个错误,它保留在"编辑"即使刷卡反弹(例如,如果你只是稍微滑动一下)也说明了状态。
好消息是,您可以使用一些UITableViewCell方法来查找解决方法。 UITableViewCell具有相应的方法,用于通知与操作相关的状态更改:
func willTransition(to state: UITableViewCellStateMask)
func didTransition(to state: UITableViewCellStateMask)
func setEditing(_ editing: Bool, animated: Bool)
var showingDeleteConfirmation: Bool { get }
转换(和动画)开始和结束时调用转换方法。当您滑动时,系统会调用willTransition
和didTransition
(状态为.showingDeleteConfirmationMask
),showingDeleteConfirmation
将为true
。 setEditing
也会调用true
。
虽然这仍然是错误的(除非您实际公布按钮,否则单元格不能成功编辑),didTransition
是一个回调,您可以在其中检查动作视图是否确实可见。我不认为有任何可靠的方法可以做到这一点,但也许只是检查单元格contentView
占用大部分边界就足够了。
答案 1 :(得分:2)
所以最后,工作解决方案最终与@ncke和@hybridcattt建议的有点不同。
@ ncke解决方案的问题在于,在此滑动/点按互动期间未调用func scrollViewDidEndDecelerating(_ scrollView: UIScrollView)
,因此永远不会调用变通方法。
@ hybridcattt解决方案的问题是那些UITableViewCell
回调过早被调用,所以如果你进行快速轻击操作,UITableViewCellDeleteConfirmationView
仍然是单元格子视图的一部分那些回调被调用。
最好的方法似乎是覆盖willRemoveSubview(_ subview: UIView)
的{{1}}功能。每次UITableViewCell
被删除时,无论是在正常滑动关闭期间,还是在这种快速滑动快速点击方案中,都会可靠地调用此方法。
UITableViewCellDeleteConfirmationView
正如@hybridcattt和@ncke建议的那样,在您的控制器中,您可以挂钩此代理并将缺少的事件发送到 protocol BugFixDelegate {
func editingEnded(cell: UITableViewCell)
}
class CustomCell: UITableViewCell {
weak var bugFixDelegate: BugFixDelegate?
override func willRemoveSubview(_ subview: UIView) {
guard String(describing: type(of: subview)) == "UITableViewCellDeleteConfirmationView" else {return }
endEditing(true)
bugFixDelegate.editingEnded(cell: self)
}
}
和UITableView
UITableViewDelegate
答案 2 :(得分:1)
我并不是说这是有史以来最好的事情,但如果你想要一个解决方法,这可能是一个开始:
extension UITableView {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
for cell in self.visibleCells {
if cell.isEditing && (cell.subviews.count < 3 || cell.subviews[2].frame.origin.x < 30.0) {
print("\(cell) is no longer editing")
cell.endEditing(true)
if let indexPath = self.indexPath(for: cell) {
self.delegate?.tableView?(self, didEndEditingRowAt: indexPath)
}
}
}
}
}
这个想法是UITableView是UIScrollView的子类。虽然前者的代表方法似乎已被打破,但后者仍在被召唤。一些实验产生了这个测试。
只是一个想法:)您可能更喜欢继承UITableView而不是扩展,以本地化黑客。
答案 3 :(得分:0)
这是我的解决方案。享受。
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
if #available(iOS 10.0, *) {
return .none;
} else {
return .delete;
}
}