使用UIPanGestureRecognizer
我的细胞可以平移。我的问题是,我只希望一次淘汰一个单元格。为此,我添加了一些尝试:
选项1,为每个单元格使用Bool
属性:
class PannableCell: UITableViewCell {
weak var controller: TableViewController?
var isPanning = false
let panGesture = UIPanGestureRecognizer()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
panGesture.addTarget(self, action: #selector(handlePan))
contentView.addGestureRecognizer(panGesture)
}
func handlePan(recognizer: UIPanGestureRecognizer) {
guard let cells = controller?.tableView.visibleCells.filter({ $0 != self }) else { return }
guard !cells.contains(where: { ($0 as? PannableCell)?.isPanning ?? false }) else { return }
if recognizer.state == .began { isPanning = true }
if recognizer.state == .changing { } //moving cell
if recognizer.state == .ended {
UIView.animate(withDuration: 0.5, animations: { }) {
if $0 { self.isPanning = false }
}
}
}
}
使用此代码,一次只能平移一个单元格。不幸的是,有些情况(约5-10%)可以淘汰多个细胞。我怀疑它与被淘汰或敲击时重复使用的细胞有关。
我知道我应该让视图控制器处理MVC模型中所述的控件。我不确定它是否能解决之前提到的问题。
有什么建议吗?
答案 0 :(得分:1)
你可以这样做:
if recognizer.state == .began { self.isPanning = true }
我想在你设置isPanning = true之前,识别器可以触发对你的句柄方法的另一个调用,这个调用也将通过,并且最终都将结束:
if recognizer.state == .began { isPanning = true }
我不知道这是什么语言,但你必须使用一些锁来在handle方法的开头和检查状态后阻塞线程。开始你可以释放锁,因此在方法的乞讨条件下将看到已经有一个isPanning = true的单元格。你也可以使把手线程安全!
好的,我读了一些关于它的内容,显然在swift中没有良好的同步,但是有足够好的文档。检查了这一个:
https://developer.apple.com/reference/uikit/uigesturerecognizerdelegate
在您的情况下,您必须添加一个委托并实施:
optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool
试试这样:
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
panGesture.delegate = self
panGesture.addTarget(self, action: #selector(handlePan))
contentView.addGestureRecognizer(panGesture)
}
func gestureRecognizer(UIGestureRecognizer, shouldRequireFailureOf:UIGestureRecognizer) -> Bool {
if (gestureRecognizer == panGesture && (otherGestureRecognizer.view.isDescendantOfView(gestureRecognizer.view)) {
return true
} else {
return false
}
}