UITouch
在触控事件发生之后,我们会从UIEvent 中,收到代表触控事件的UITouch 实例。
UITouch起初是个非常单纯的实例,我们顶多只会使用-locationInView:
判断触控事件发生在view的哪个位置上(CGPoint),以及用-tapCount
知道碰触了几下,以及用-timestamp
知道触控事件的时间。
但随着iOS 不断演进,UIEvent 与UITouch 也变得愈来愈复杂,尤其是在iOS 9 推出之后,突然一次出现了非常多新的API。
触控屏幕的扫描速率
在iOS 9之后,增加了coalescedTouchesForTouch
这个属性,主要原因是iPad Air 2硬体性能的提升。
当我们看到touchesBegan:withEvent:
这些API,大概可以想到,我们会在每一轮runloop收到一次touch实例,所以触控萤幕在接收touch实例的速度,大概会是跟runloop的速度差不多。于是,当开发者在开发一些在iPad上的绘图应用的时候,往往就觉得在iPad上会有延迟的现象:手指已经在萤幕上画过去了,但是画面却是慢慢地更新。
苹果在iPad Air 2的触控萤幕上加快了对触控事件的扫描频率,比起之前的iPad快上一倍,但是,run loop的速度并没有改变,因此,在iOS 9的API中,会把这些比以前来得多的触控事件,变成UIEvent物件的coalescedTouchesForTouch:
method,在这个method中,可以拿到更多的UITouch,可以让我们在搭配iOS 9的iPad Air 2上抓到更多touch物件,绘制更精细的线条。
UIEvent同时也多了一组叫做predictedTouchesForTouch:
的method,预测下一个触控事件可能出现的位置,因此,即使这个触控事件还没有发生,但我们便可以偷吃步先去做绘图相关的工作,让画面看起来即时更新。
相关说明请参见WWDC 2015影片WWDC 2015 Advanced Touch Input on iOS。
3D Touch
苹果在iPhone 6S上加入了3D Touch功能,除了在App这层加了shortcut、在view controller这层加入了peek and pop功能(实作UIViewControllerPreviewingDelegate protocol)之外,便是UITouch物件本身也加入了force
与maximumPossibleForce
等属性,用来判断触控的力道。
在iOS 9与iPhone 6S上,touchesMoved:withEvent:
的行为也发生了变化,原本只有Touch事件的X轴或Y轴有改变的时候,系统才会触发touchesMoved:withEvent:
,但是在有了3D Touch之后,触控压力的改变,也会触发touchesMoved:withEvent:
,换言之,这个method被调用的时候,我们不能够假设用户的手指真的移动了位置,很有可能只是压力的改变而已。要知道手指的位置是否真的移动了,我们需要另外比对UITouch物件的X轴或Y轴的位置,不然就可能会把单点误判成Swipe。这部份说明请参见iOS 9.1 Release Note。
当然,如果只是要知道用户是否单点在一个位置上,用UIGestureRecognizer 还是比较简单,也是比较保险的方法。
Apple Pencil
在iOS 9 推出的同时,Apple 同时宣布了iPad Pro 这条产品线,在iPad Pro 上可以使用Apple Pencil 这款输入装置做更精密的手写。于是,苹果在iOS 9.1 SDK 中增加不少与Apple Pencil 相关的API。摘录iOS 9.1 SDK 的release note 部分如下:
- UITouch增加了
type
属性,用来判断这个触控事件是来自于直接、间接的触控,或是来自于Apple Pencil - UITouch物件原本就有
-locationInView:
与-previousLocationInView
这两个method表示触控发生的位置,在使用Apple Pencil的时候,我们可以透过-preciseLocationInView:
与precisePreviousLocationInView:
这两个method,知道更精细的触控位置。 altitudeAngle
、azimuthAngleInView:
与azimuthUnitVectorInView:
可以让你知道Apple Pencil的高度与方位。- UIEvent中的
predictedTouchesForTouch:
method只预测了下一个触控事件可能的位置,但有了Apple Pencil之后,我们还会想要预测接下来Apple Pencil的高度、方位与压力等资讯。我们便可以透过estimatedProperties
与estimatedPropertiesExpectingUpdates
这些属性取得。