金田html
今天要講的主題是iOS 9高級觸摸輸入,更準確地講,是在iOS9上如何減小觸摸輸入到屏幕顯示的延遲程度,這次將分 低延遲渲染(iOS9 渲染性能優化)和 觸摸點方案改進 兩個方面來介紹。swift
低延遲渲染性能優化
1)介紹性能
一直以來,iOS 裏面的觸摸手勢延遲(latency)是一個極爲影響用戶體驗,比較頭痛,卻又比較棘手的一個問題。試想咱們畫一條線,手勢稍快一點就會是手指在前面跑,畫的線在後面追。優化
圖1.1 手勢延遲示意圖(截取自WWDC演示文檔)spa
值得咱們關注的是,這次發佈的iOS 9操做系統,專門爭對這一問題,進行了優化。操作系統
首先,iOS9從獲取到手勢點到顯示至屏幕的各環節,進行性能優化,縮短每一個手勢事件反饋到屏幕的時間延時(latency)。htm
圖2 iOS8 Touch與渲染管理示意圖(截取自WWDC演示文檔)blog
圖3 iOS9 Touch與渲染管理示意圖(截取自WWDC演示文檔)事件
從上圖示能夠看出,iOS 9系統對系統進行了優化,從而提高App、以及App內容渲染各環節的性能,進而達到下降延遲的目的。
2)使用
上面講了這麼多,到底該如何使用低延時(low latency)功能呢?
// For lowest latency (default):
layer.presentsWithTransaction = false;
// For synchronizing with CA:
layer.presentsWithTransaction = true
當採用OpenGL ES作渲染時,只須要給CAEAGLLayer presentsWithTransaction屬性設置爲false(默認),便可下降延遲。若是是採用的Metal,則只要將MTKView的presentsWithTransaction屬性設置爲false(默認),便可下降延遲。
觸摸點方案改進
iOS 9在經過提高CA(Core Animation)性能減小延遲的同時,也採用一些方案來提高App的呈現效果。固然,這次iOS9爭對觸控點作了很是大的改進和優化,iOS 9新API有引入了 Touch Coalescing(觸控合併)和 Touch Prediction(觸控預測)。下面咱們就爭對Touch Coalescing(觸控合併)和 Touch Prediction(觸控預測)作相應的介紹。
一、 Touch Coalescing(觸控擬合)
iOS8及之前,App的觸摸掃描頻率、渲染幀率均是60Hz,作過繪圖功能的朋友應該對下面這張圖不會陌生。
圖2.1 60Hz掃描點直接連線效果示意圖
此外目前iPad Air 2 點掃描(Touch Scan)觸摸掃描頻率已經達到120Hz,直接將點相連,示意圖以下:
圖2.2 120Hz掃描點直接連線效果示意圖
App代碼處理的頻率一樣是60Hz,因此事實上,在iPad Air2上面,有一半的點被丟掉,但如今iOS 9的Touch Coalescing 有完美解決這一問題,iOS9有將沒被直接響應的點合併(Coalescing)到了響應的觸摸事件內。
圖2.3 iOS 9點擬合(Coalescing)示意圖
Touch Coalescing 功能的應用
[swift 代碼]
for touch in touches {
let line = lineForTouch(touch)
for coalescedTouch in event.coalescedTouchesForTouch(touch) {
addTouchSample(coalescedTouch, toLine: line)
}
}
[Object-c 代碼]
for (UITouch *coalescedTouche in [event coalescedTouchesForTouch:[touches anyObject]]) {
//Use UITouch
}
二、Touch Prediction(觸摸點預測)
經過該方部分,能夠預測接下來的觸摸點將來的大體走向。如示意圖:
圖2.4 觸摸點預測示意圖
經過該部分,能提早預測到觸摸點將來將要走的可能趨勢。
Touch Prediction 用法
[Swift 代碼]
for touch in touches {
let line = lineForTouch(touch)
for predictedTouch in event.predictedTouchesForTouch(touch) {
addTouchSample(predictedTouch, toLine: line)
}
}
[Objective-c 代碼]
for (UITouch *touch in touches) {
for (UITouch *predictedTouch in [event predictedTouchesForTouch:touch]) {
//Use Predicted Touch
}
}