Phone中處理觸摸屏的操作,在3.2之前是主要使用的是由UIResponder而來的如下4種方式:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
但是這種方式甄别不同的手勢操作實在是麻煩,需要你自己計算做不同的手勢分辨。後來。。。
蘋果就給出了一個比較簡便的方式,就是使用UIGestureRecognizer。
六種手勢識别的class:
UITapGestureRecognizer
UIPinchGestureRecognizer
UIPanGestureRecognizer
UISwipeGestureRecognizer
UIRotationGestureRecognizer
UILongPressGestureRecognizer
點選手勢響應
[img]http://dl.iteye.com/upload/attachment/0082/6989/4e7ecc92-a21a-3b46-aeb5-597763fed75f.png[/img]
單次響應和持續響應
[img]http://dl.iteye.com/upload/attachment/0082/6991/e2fcdbeb-7127-381c-9576-2b0f7a813eb0.png[/img]
手勢識别幾種狀态的轉化:
UIGestureRecognizerStateRecognized
UIGestureRecognizerStateBegan
UIGestureRecognizerStateChanged
UIGestureRecognizerStateEnded
UIGestureRecognizerStateCancelled
UIGestureRecognizerStateFailed
[img]http://dl.iteye.com/upload/attachment/0082/7158/1836b196-c75f-3144-95da-2cb83d92f1e3.png[/img]
如果在一個view上有多個手勢,可以使用UIGestureRecognizer和它的delegate方法來處理。
手勢識别是具有互斥的原則的,比如單擊和輕按兩下,如果它識别出一種手勢,其後的手勢将不被識别。可以使用requireGestureRecognizerToFail:方法來取消手勢
允許同時手勢識别:
gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
如果兩個手勢有單項關系,就是一個手勢阻止另外一個手勢,那麼使用:
canPreventGestureRecognizer:或者canBePreventedByGestureRecognizer:
在IOS6之後,許多控件隻支援單種手勢:
UIButton, UISwitch, UIStepper, UISegmentedControl, and UIPageControl支援單擊
A single finger swipe on the knob of a UISlider, in a direction parallel to the slider.
A single finger pan gesture on the knob of a UISwitch, in a direction parallel to the switch.
多點觸控和觸摸階段:
[img]http://dl.iteye.com/upload/attachment/0082/7168/63cc99f4-7a5d-379e-89f4-1e5d2bf37e88.png[/img]
觸摸傳送路徑:
[img]http://dl.iteye.com/upload/attachment/0082/7170/b4840760-3279-3fa0-834e-2d0c3a88baf6.png[/img]
如果被touch對象被識别到,那麼window不會傳送給view了。
UIGestureRecognizer有兩個屬性:
delaysTouchesBegan(預設是NO):讓手勢識别到這個動作,如果設定成yes,那麼view的響應會比較慢
delaysTouchesEnded(預設是YES):手勢可能會取消,留足時間。
事件傳送,Responder chain:
1. The touch is within the bounds of view A, so it checks subviews B and C.
2. The touch is not within the bounds of view B, but it’s within the bounds of view C, so it checks subviews
D and E.
3. The touch is not within the bounds of view D, but it’s within the bounds of view E.
View E is the lowest view in the view hierarchy that contains the touch, so it becomes the hit-test view.
[img]http://dl.iteye.com/upload/attachment/0082/7594/4c50fcd8-b91a-3e89-8e93-2ea00f16b81c.png[/img]
The responder chain是一系列關聯的responder對象
得先重寫canBecomeFirstResponder方法,傳回YES;
responder對象包括:Touch events、Motion events(sharking)、Remote control events、Action messages、Editing-menu messages、Text editing
The responder chain on iOS
[img]http://dl.iteye.com/upload/attachment/0082/7596/d4fd9c9f-fcd0-3c48-8dd5-0c6f0a118b8f.png[/img]
通過方法nextResponder來傳遞響應
隻要是UIResponder的子類都可以處理事件,就像UIView、UIViewController、UIControl、UIApplication or UIWindow,處理類需要實作touch對應的方法,并且設定userInteractionEnabled為YES,而且處理的view等不能為空或者隐藏
多點觸碰:
[img]http://dl.iteye.com/upload/attachment/0082/7598/06503c55-5bab-3b17-8818-ea49b2230816.png[/img]
觸摸對象的檢索和查詢:
multipleTouchEnabled屬性預設為NO,表示隻能響應第一個觸碰事件。通過locationInView:擷取位置資訊,通過allTouches方法擷取所有的touch,指定一個Window,使用touchesForWindow:擷取所有的touch,指定一個view,使用touchesForView:擷取所有的touch
[img]http://dl.iteye.com/upload/attachment/0082/7604/f3f032ca-af67-3c40-8ff1-dad4181a496d.png[/img]
[img]http://dl.iteye.com/upload/attachment/0082/7606/fd827142-a396-37cf-bc6f-99c9d4533b72.png[/img]
[img]http://dl.iteye.com/upload/attachment/0082/7608/e2480999-51b6-3dee-96ac-d943d9461d06.png[/img]
要處理複雜的手勢事件,需要把屬性multipleTouchEnabled設定為YES,設定屬性exclusiveTouch(預設是NO),不會阻止其他view接受觸摸,設定為YES就會阻止其他view接受觸碰
B和C都不能接受touch
[img]http://dl.iteye.com/upload/attachment/0082/7612/c995dafb-f817-3802-9852-979cbec6f756.png[/img]
把userInteractionEnabled設定成NO就關閉了事件的響應鍊。不過也可以通過beginIgnoringInteractionEvents和endIgnoringInteractionEvents來間斷的阻止響應鍊(一般動畫的時候,不需要觸碰)
如果要攔截touch,可以重寫方法hitTest:withEvent:,不需要實作 touchesBegan:withEvent:, touchesEnded:withEvent:, or touchesMoved:withEvent:
轉發touch事件
Best Practices for Handling Multitouch Events
非常實用
螢幕方向改變識别
Motion Events
如果應用程式想要使用陀螺儀或者加速器等硬體,那麼需要在plist檔案中定義
key:UIRequiredDeviceCapabilities value:accelerometer、gyroscope
擷取裝置的移動:Motion events是通過三個類來呈現移動的
CMAccelerometerData:
CMGyroData:
CMDeviceMotion:
CMMotionManager是核心的管理類,它提供兩種方式來擷取資料,推、拉(推薦)
Common update intervals for acceleration events
[img]http://dl.iteye.com/upload/attachment/0082/8794/b0cdb14f-0251-30ec-a1a5-1c2d98019fdf.png[/img]
Accessing accelerometer data in MotionGraphs
Accessing gyroscope data in MotionGraphs
Starting and stopping device motion updates
遠端控制