2017-06-13 67 views
1

我在用Swift编程的iOS应用程序中使用UIPanGestureRecognizer,让用户控制图像的颜色分量。虽然更新只需要非常小的一秒,但整体外观却很差,因为UIPanGestureRecognizer被称为每秒几十次。确保这不会发生的最佳方法是什么?现在我只是让它只是每三次更新就调用一次函数,但这似乎并不理想。UIPanGestureRecognizer更新间隔

+0

你可以发送平移手势操纵UIColor的代码吗? –

回答

1

我相信你的解决方案(只考虑每第三次更新)是基于一个错误的假设,如果你不能足够快地回应手势,他们会积压。但这不是它的工作原理。如果主线程无法跟上手势,它会放弃手势,不会积压。事实上,您的解决方案(考虑每三次更新一次)只会引入延迟而不是解决问题。

因此,我们的目标是让触感更加灵敏。这里有两种可能的问题:

  1. 潘手势需要一点点运动之前它成功地确定为泛,从而可以有短暂的延迟最初识别手势之前。

  2. 虽然有各地的手势识别此之前问题的技巧,还有第二个功能,可能当你不使用手势识别和实施touchesBegantouchesMoved等,来代替。您不仅可以避免先识别姿势的滞后,还可以参与预测性触摸。

因此,在设备上具有高性能触摸,你可以这样做:

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代码,它可以进行相当显着的性能更改),并在物理设备上进行测试,因为设备中的图形性能与其非常不同在模拟器中。

但是,如果您使用预测触摸并测试物理设备上的发布版本,则通常应该获得不错的性能。但是很难说没有看到一些代码。