2017-06-13 95 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代碼,它可以進行相當顯着的性能更改),並在物理設備上進行測試,因爲設備中的圖形性能與其非常不同在模擬器中。

但是,如果您使用預測觸摸並測試物理設備上的發佈版本,則通常應該獲得不錯的性能。但是很難說沒有看到一些代碼。