iOS學習之事件處理的原理

来源:http://www.cnblogs.com/gfxxbk/archive/2016/06/19/5599070.html
-Advertisement-
Play Games

在iOS學習23之事件處理中,小編詳細的介紹了事件處理,在這裡小編敘述一下它的相關原理 1、UITouch對象 在觸摸事件的處理方法中都會有一個存放著UITouch對象的集合,這個參數有什麼用呢? (1)UITouch 對象的簡介 當用戶用一根手指觸摸屏幕時,會創建一個與手指相關聯的 UITouch ...


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;
}

 

  • 從後往前遍歷子控制項,重覆前面的兩個步驟

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 先上代碼,下麵是使用例子。 上面是HTML代碼,下麵是調用方法。 調用方法很簡單吧! 再來一個處理多行數據的例子。 data2={"data":[{"帳號":"yeruzhao1","name":"葉如兆","avatar":"http:\/\/shp.qpic.cn\/bizmp\/3eJCszw ...
  • 前言: 上周天的時候有個學長找我幫忙做三張頁面,因為沒有數據交換之類的,只是單純的前端頁面,想著好久沒做東西, 看書都看煩了,所以就接了也當是練手。之前因為沒有系統的看書,所以其實很多問題都考慮的不全面,屬於知其然不知其所以然的狀態,雖然現在也還有很多要學的東西,但是知道自己的不足總比不知道強吧?而 ...
  • var myDate = new Date();myDate.getYear(); //獲取當前年份(2位)myDate.getFullYear(); //獲取完整的年份(4位,1970-????)myDate.getMonth(); //獲取當前月份(0-11,0代表1月)myDate.getDa ...
  • 註:本實例JS部分均以原生JS編寫,不善用原生JS的,可用jQuery等對三方框架改寫 先上效果圖:(樣式有點醜,可以忽略一下下,效果出來了就好,後期加到其他項目中方便更改0.0) 類似翻書效果,原本的意思是使用JS來控制的,點擊一次之後使用setInterval去控制書頁翻過去的動畫,當書頁翻轉1 ...
  • 前端之MVC應用 1、indexedDB(Model) -- 前端瀏覽器對象型資料庫,一般我們後臺用的資料庫都是關係型資料庫。那麼indexeddb有什麼特點呢: 首先,從字義上它是索引型資料庫,從實際使用中可以體現為,它需要為表創建索引才可以根據某個欄位來獲取數據,而在關係型資料庫中,這明顯是不需 ...
  • 簡要:$.Callbacks是一個生成回調管家Callback的工廠,Callback提供一系列方法來管理一個回調列表($.Callbacks的一個私有變數list),包括添加回調函數, 刪除回調函數等等...,話不多說看正文: memory的值由傳入$.Callbacks的形參對象決定,具有狀態記 ...
  • 因為有萬惡的 IE 存在,所以當Web項目初始化併進入開發階段時。 如果是項目經理,需要很明確的知道客戶將會用什麼瀏覽器來訪問系統。 明確知道限定瀏覽器的情況下,你才能從容的讓手下的封裝必要的前端組件。 本篇文章試圖從常見的上傳方式和組件進行分析,僅局限與前端,至於後端需依據業務複雜度,自行拿捏實現 ...
  • 首先要加入類庫GDataXMLNode和JSON 解析本地文件Students.txt <students> <student> <name>湯姆 </name> <age>20</age> <phone>13049640144</phone> </student> <student> <name> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...