參考
[1]http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009541-CH1-SW1
1.事件類型
主要是 觸摸事件,動作事件(甩動等),和遠端控制事件三類。
typedef enum {
UIEventTypeTouches,
UIEventTypeMotion,
UIEventTypeRemoteControl,
} UIEventType;
2.加速器和陀螺儀
UIAccelerometer 和 UIAcceleration以後可能被廢棄,所以應該使用Core Motion framework中的介面。
Notes: The UIAccelerometer andUIAcceleration classes will be deprecated in a future release, so if your application handles accelerometer events, it should transition to the Core
Motion API.
In iOS 3.0 and later, if you are trying to detect specific types of motion as gestures—specifically shaking motions—you should consider handling motion events (UIEventTypeMotion)
instead of using the accelerometer interfaces. If you want to receive and handle high-rate, continuous motion data, you should instead use the Core Motion accelerometer API. Motion events are described in“Shaking-Motion
Events.”
3.事件響應鏈
簡單說就是:view->viewController->supperview 如此迴圈。具體過程如下
- The hit-test view or first responder passes the event or message to itsview controller if it has one; if the view doesn’t have a view controller, it passes the event or message to its superview.
- If a view or its view controller cannot handle the event or message, it passes it to thesuperview of the view.
- Each subsequent superview in the hierarchy follows the pattern described in the first two steps if it cannot handle the event or message.
- The topmost view in the view hierarchy, if it doesn’t handle the event or message, passes it to thewindow object for handling.
- The UIWindow object, if it doesn’t handle the event or message, passes it to thesingleton
application object.
If the application object cannot handle the event or message, it discards it.
4.hitTest尋找被點中的view
使用者點擊螢幕,系統是如何尋找當前被點擊所在的view,如果view是隱藏的,透明的,userInteractionEnabled 為NO 都不被列入尋找的目標。
系統尋找響應的view是從上往下的,事件的響應鏈是從下往上的。
具體說明如下
- Touch events. The window object uses hit-testing and the responder chain to find the view to receive the touch event. In hit-testing, a window callshitTest:withEvent:
on the top-most view of the view hierarchy; this method proceeds by recursively callingpointInside:withEvent:
on each view in the view hierarchy that returnsYES, proceeding down the hierarchy until it finds the subview within whose bounds the touch took place. That view becomes the hit-test view.
方便理解,拷了一段代碼,系統的實現應該也類似的。
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ return CGRectContainsPoint(self.bounds, point);}- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ if (self.hidden || !self.userInteractionEnabled || self.alpha < 0.01 || ![self pointInside:point withEvent:event]) { return nil; } else { for (UIView *subview in [self.subviews reverseObjectEnumerator]) { UIView *hitView = [subview hitTest:[subview convertPoint:point fromView:self] withEvent:event]; if (hitView) { return hitView; } } return self; }}
5.手勢識別
系統支援6中基本手勢
Tapping
(any number of taps) UITapGestureRecognizer
Pinching in and out (for zooming a view)UIPinchGestureRecognizer
Panning or draggingUIPanGestureRecognizer
Swiping (in any direction)UISwipeGestureRecognizer
Rotating (fingers moving in opposite directions)UIRotationGestureRecognizer
Long press (also known as “touch and hold”)UILongPressGestureRecognizer
使用的方法就是 建立對應執行個體,然後 addGestureRecognizer 加入對應的view即可,當識別出來則調用響應的回掉函數。
如果要實現自己的手勢識別,繼承 UIGestureRecognizer,重寫以下四個方法,自己在裡面實現手勢識別演算法。具體看文檔吧。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
其他沒什麼特別的了。