【问题标题】: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 模型中所述的控制事物。我不确定它是否能解决前面提到的问题。

有什么建议吗?

【问题讨论】:

    标签: swift uitableview uipangesturerecognizer


    【解决方案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
        }
    }
    

    【讨论】:

    • 感谢您的回答,它没有解决我的问题,但间接地我找到了解决它的方法。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    相关资源
    最近更新 更多