你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS編程技術 >> iOS學習之事件處理的原理

iOS學習之事件處理的原理

編輯:IOS編程技術

在iOS學習23之事件處理中,小編詳細的介紹了事件處理,在這裡小編敘述一下它的相關原理

1、UITouch對象

在觸摸事件的處理方法中都會有一個存放著UITouch對象的集合,這個參數有什麼用呢?

(1)UITouch 對象的簡介

  • 當用戶用一根手指觸摸屏幕時,會創建一個與手指相關聯的 UITouch 對象

  • 一根手指對應一個 UITouch 對象

  • UITouch 的作用

  保存著根手指相關的信息,比如觸摸的位置、時間、階段

  • 當手指移動時,系統會更新同一個 UITouch 對象,使之能夠一直保持該手指在的觸摸位置

  • 當手指離開屏幕時,系統會銷毀相應的 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的坐標系(以View的左上角為原點(0,0))

  • 當方法一調用時傳入的View參數為 nil 的話,返回的是觸摸點在 UIWindow 的位置

 實例代碼:

// 當手指在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;
}

 

  • 從後往前遍歷子控件,重復前面的兩個步驟
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved