防止多个可平移的表格视图单元格被平移

Posted

技术标签:

【中文标题】防止多个可平移的表格视图单元格被平移【英文标题】:Preventing multiple pannable table view cells being panned 【发布时间】:2016-12-12 03:30:30 【问题描述】:

我的单元格可以使用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 模型中所述的控制事物。我不确定它是否能解决前面提到的问题。

有什么建议吗?

【问题讨论】:

【参考方案1】:

你可以这样:

if recognizer.state == .began  self.isPanning = true 

我猜在您设置 isPanning = true 之前,识别器可以触发对您的句柄方法的另一个调用,该方法也将通过并且最终都将在:

if recognizer.state == .began  isPanning = true 

我不知道这是什么语言,但是您必须在句柄方法的开头和检查状态之后使用一些锁来阻塞线程。开始你可以释放锁,因此在方法请求的条件下会看到已经有一个 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
    

【讨论】:

感谢您的回答,它没有解决我的问题,但间接地我找到了解决它的方法。谢谢!

以上是关于防止多个可平移的表格视图单元格被平移的主要内容,如果未能解决你的问题,请参考以下文章

使用平移手势选择多个表格视图单元格

处理 UITableView 单元格上的平移手势

将集合视图中的单元格移动到另一部分的最后一个单元格之外不起作用

如何实现像 iOS MAIL 应用程序这样的平移手势,以便一次只打开一个单元格?

带有内容的表格视图单元格被白色覆盖?

为啥当我在平移单元格时更改 UIImageView 的图像时,整个视图会重置一秒钟?