iOS中事件處理流程
iOS開發者大都略知一二事件的傳遞機制,但是對于事件在處理程序中所呼叫的具體方法和方法所應用的場景是比較模糊的.今天我就簡單的介紹一下事件處理流程和具體的使用.
事件處理流程:
1.當用戶點擊螢屏時會產生一個觸摸事件,系統會將該事件包裝成一個UIEvent加入到一個由UIApplication管理的事件佇列中.
2.UIApplication會從事件佇列中取出最前面的事件進行分發以便處理,通常先發送給應用程式的主視窗(UIWindow)
3.主視窗會呼叫hitTest:withEvent:方法在視圖(UIView)層次結構中找到最適合的UIView來處理觸摸事件.(hitTest:withEvent其實也是UIView的一個方法,UIWindow繼承自UIView,因此主視窗UIWindow也是屬于視圖的一種)
hitTest:withEvent:方法大致處理流程時這樣的:
呼叫當前視圖的pointInside:withEvent:方法判斷觸摸點是否在當前視圖內:
- 若pointInside:withEvent:方法回傳NO,說明觸摸點不在當前視圖內,則當前視圖的hitTest:withEvent:方法回傳nil
- 若pointInside:withEvent:方法回傳YES,說明觸摸點在當前視圖內,則遍歷當前視圖的子控制元件(subViews),然后呼叫子控制元件的hitTest:withEvent:和pointInside:withEvent:方法來判斷觸摸點是否在某個子控制元件上.子視圖的遍歷順序時top到bottom,即從subViews陣列的末端向前遍歷,直到有子視圖的hitTest:withEvent:方法回傳為非空物件或者全部子視圖遍歷完畢.
- 若第一次有子視圖的hitTest:withEvent:回傳非空物件,則當前視圖的hitTest:withEvent:方法就回傳此物件,處理結束
- 若所有的子視圖的hitTest:withEvent:方法回傳nil,則當前視圖的hitTest:withEvent:回傳當前視圖自身(self).
4.最終,這個觸摸事件交給主視窗的hitTest:withEvent方法回傳的視圖物件去處理.
舉例:
1.擴大UIButton的回應區域(上下左右各增加10)
重寫UIButton的pointInside:withEvent:方法
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if (CGRectContainsPoint(CGRectInset(self.bounds, -10, -10), point)) {
return YES;
}
return NO;
}
2.子控制元件超出父控制元件的bounds如何回應事件
一般超出部分是不會回應事件的,所以我們要重寫父控制元件的pointInside:withEvent:方法來處理
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL flag = NO;
for (UIView *view in self.subviews) {
if (CGRectContainsPoint(view.frame, point)){
flag = YES;
break;
}
}
return flag;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/262066.html
標籤:其他
下一篇:Splash閃屏頁的開發(詳解)
