我在使用Swift编写的iOS应用程序中使用UIPanGestureRecognizer,让用户控制图像的颜色分量。虽然更新只需要很短的一小部分时间,但总体上看起来是滞后的,因为UIPanGestureRecognizer每秒会被调用几十次。确保这种情况不会发生的最佳方法是什么?现在我只想让它每三次更新一次就调用一次函数,但这似乎并不理想。
发布于 2017-06-14 04:24:44
我相信你的解决方案(只考虑每三次更新)是基于一个错误的假设,即如果你不能足够快地响应手势,它们就会积压。但这不是它的工作方式。如果主线程跟不上手势,它会丢弃手势,而不是积压。事实上,你的解决方案(考虑每三次更新)只会引入滞后,而不是解决它。
因此,我们的目标是让触摸更具响应性。这里有两个可能的问题:
touchesBegan、touchesMoved等时,可能会有第二个功能。你不仅可以避免第一次识别手势的延迟,而且你还可以参与预测触摸。因此,对于设备上的高性能触摸,您可以执行以下操作:
var start: CGPoint?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
start = touches.first?.location(in: view)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let point: CGPoint
if let predictedTouch = event?.predictedTouches(for: touch)?.last {
point = predictedTouch.location(in: view)
} else {
point = touch.location(in: view)
}
updateColor(for: point)
}
// make sure when you're done to update in `touchesEnded`, too, in case
// the last `touchesMoved` generated a predictive touch, but when we're
// done, we really want to use the final real `location`
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
updateColor(for: touch.location(in: view))
}
private func updateColor(for point: CGPoint) {
// do something with `start` and `point` to adjust the color
}请注意,根据我的经验,您不会总是在模拟器中体验预测触摸,因此请确保在物理设备上进行测试。
值得注意的是,还有第三个潜在的问题。具体地说,如果您的“更改颜色组件”花费了太长的时间来呈现一致的60 fps,那么您可能需要在仪器中进行一些时间的分析,以确定问题的根源。但是我们不能在没有看到你的问题的可重现的例子(即MCVE)的情况下发表评论。
此外,请确保您进行“发布”构建(取决于您的Swift代码,它可以进行相当重要的性能更改),并在物理设备上测试它,因为设备中的图形性能与模拟器中的图形性能非常不同。
但是,如果您使用预测触摸并在物理设备上测试发布版本,您通常应该会获得不错的性能。但是,如果不看一些代码就很难说出来。
https://stackoverflow.com/questions/44529047
复制相似问题