天天看點

Event programming guide

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

遠端控制