拖动 Swift UIView 时出现故障

Glitching When Swift UIView is Dragged

我在 iOS 项目中有一个视图,该视图将被拖动到主视图中。风景。我已将平移手势附加到该视图 (paletteView),然后四处移动效果很好。

但是,移动开始时的“故障”。这不会发生在第一次行动中,而是发生在随后的行动中。我认为发生的事情与 paletteView 的约束有关。它在主视图中从 100,100 处开始,但当然只要拖动结束,除非我更改它,否则它会快速返回到该位置。因此,每当平移开始时,我都会获取调色板的位置,并更新约束。这也有效,但它似乎会在下一次手势开始时产生闪光。这是主要代码:

    @objc func palettePan(_ sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: view)
        switch sender.state {
        case .began:
            paletteLeading?.constant = paletteView!.frame.origin.x
            paletteTop?.constant = paletteView!.frame.origin.y
            paletteView?.setNeedsUpdateConstraints()
        case .changed:
            paletteView!.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
        case .ended:
            print("done \(paletteView!.frame)")
        default:
            _ = true
        }
    }

同样,这工作正常,但对于调色板的短暂“闪光”,位置不对。我不知道这是从哪里来的。

您需要在更新约束的同时重置transform,此时您正在将约束更新到新位置,但视图仍会通过最终翻译进行转换前一个平移,直到第一个 changed 平移手势事件通过。

因此您的 palettePan 函数将变为:

@objc func palettePan(_ sender: UIPanGestureRecognizer) {
    let translation = sender.translation(in: view)
    switch sender.state {
    case .began:
        paletteLeading?.constant = paletteView!.frame.origin.x
        paletteTop?.constant = paletteView!.frame.origin.y
        paletteView?.setNeedsUpdateConstraints()
        paletteView?.transform = .identity // Reset the transform
    case .changed:
        paletteView!.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
    case .ended:
        print("done \(paletteView!.frame)")
    default:
        _ = true
    }
}

尽管我实际上会在平移手势结束时而不是在新手势开始时更新约束和变换:

@objc func palettePan(_ sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: view)
        switch sender.state {
        case .changed:
            paletteView?.transform = CGAffineTransform(translationX: translation.x, y: translation.y)
        case .ended, .cancelled, .failed:
            paletteLeading?.constant = paletteView!.frame.origin.x
            paletteTop?.constant = paletteView!.frame.origin.y
            paletteView?.setNeedsUpdateConstraints()
            paletteView?.transform = .identity // Reset the transform
        default:
            _ = true
        }
    }