iOS學習之事件處理的原理,ios事件原理
在iOS學習23之事件處理中,小編詳細的介紹了事件處理,在這裡小編敘述一下它的相關原理
1、UITouch對象
在觸摸事件的處理方法中都會有一個存放著UITouch對象的集合,這個參數有什麼用呢?
(1)UITouch 對象的簡介
儲存著根手指相關的資訊,比如觸摸的位置、時間、階段
提示:iPhone 開發中,要避免使用雙擊事件!
(2)UITouch 的屬性
@property (nonatomic, readonly, retain) UIWindow *window;
@property (nonatomic, readonly, retain) UIView *view;
- 短時間內點按螢幕的次數,可以根據 tapCount 判斷單擊、雙擊或更多的點擊
@property (nonatomic, readonly) NSUInteger tapCount;
@property (nonatomic, readonly) NSTimeInterval timestamp;
@property (nonatomic, readonly) UITouchPhase phase;
(3)UITouch 的方法
// 傳回值表示觸摸在View上的位置 - (CGPoint)locationInView:(UIView *)view;// 該方法記錄了前一個觸摸點的位置- (CGPoint)previousLocationInView:(UIView *)view;
執行個體代碼:
// 當手指在view上移動的時候- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ NSLog(@"%s",__func__); // 擷取UITouch對象 UITouch *touch = [touches anyObject]; // 擷取當前點 CGPoint curP = [touch locationInView:self]; // 擷取上一個點 CGPoint preP = [touch previousLocationInView:self]; // 擷取x軸位移量 CGFloat offsetX = curP.x - preP.x; // 擷取y軸位移量 CGFloat offsetY = curP.y - preP.y; // 修改view的位置(frame,center,transform) self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);// self.transform = CGAffineTransformMakeTranslation(offsetX, 0);}
預設不支援多個手指,要修改 Multiple Touch 屬性,在 storyboard 中將這個屬性打鉤就可以
2、原理(1)事件的產生和傳遞
發生觸摸事件後,系統會將該事件加入到一個由 UIApplication 管理的事件隊列中
UIApplication 會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,通常,先發送事件給應用程式的主視窗(keyWindow)
主視窗會在視圖階層中找到一個最適合的視圖來處理觸摸事件,這也是整個事件處理過程的第一步
找到合適的視圖控制項後,就會調用視圖控制項的 touches 方法來做具體的事件處理
touchesBegan...
touchesMoved...
touchesEnded...
(2)UIView不接收觸摸事件的三種情況
userInteractionEnabled = NO;
hidden = YES;
alpha = 0.0 ~ 0.1
(3)如何找到最適合的控制項
- 判斷自己是否能接收觸摸事件,底層實現方法:hitTest: withEvent:
// 作用:就是用來尋找最合適的view// 什麼時候調用:當事件傳遞給控制項的時候,就會調用控制項的這個方法,去尋找最合適的view// point:當前的觸摸點,point這個點的座標系就是方法調用者- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ // 調用系統的做法去尋找最合適的view,返回最合適的view UIView *fitView = [super hitTest:point withEvent:event]; return fitView;}
該方法的傳回值就是事件處理的視圖控制項
當該方法在 UIWindow 類中重寫,要使無論點哪裡都是最底下白色的視圖進行處理,就返回 self.subviews[0]。
判斷觸摸點是否在自己身上,底層實現方法:pointInside: withEvent:
// 作用:判斷當前這個點在不在方法調用者(控制項)上// 在判斷是否是最適合的控制項的時候調用- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ return YES;}