在使用微信查看聯(lián)系人頭像的時候界轩,可以點擊頭像使之放大、進而填充整個window衔瓮,可以對大圖
進行雙擊浊猾、縮放、平移等操作热鞍,總的來說這個過程的編碼也不復(fù)雜葫慎,但是涉及到UIWindow、手勢
識別方面的知識薇宠,有必要總結(jié)一下偷办。
UIWindow
UIWindow是一種特殊的UIView,我們一般在程序中這樣來指定App的UIWindow:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITabBarController * tabBarController = [[UITabBarController alloc] init];
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
一個App中通常只有一個UIWindow昼接,作為所有視圖的容器爽篷。在編碼的過程中這樣來獲得App的keyWindow:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
當(dāng)然,我們也可以手動創(chuàng)建多個UIWindow慢睡,多個Window的顯示順序是根據(jù)UIWindowLevel進行排序的逐工,
IOS默認(rèn)定義了三個等級:
const UIWindowLevel UIWindowLevelNormal; //0.0
const UIWindowLevel UIWindowLevelAlert; //2000.0
const UIWindowLevel UIWindowLevelStatusBar; //1000.0
值得注意的是:UIWindow是嚴(yán)格按照Level來顯示的,與keyWindow的設(shè)置順序無關(guān)漂辐,在使用的
過程中常用的場景是需要全屏幕覆蓋一個蒙層泪喊。
事件處理
任何一款移動設(shè)備都會有事件處理,允許操作系統(tǒng)能夠?qū)τ脩舻牟僮鬟M行響應(yīng)髓涯,IOS中的用戶事件
分為三種:
1. 觸摸事件:通過觸摸袒啼、手勢進行觸發(fā)
2. 運動事件:通過加速器進行觸發(fā),例如手機晃動
3. 遠(yuǎn)程控制事件:遠(yuǎn)程設(shè)備觸發(fā),例如耳機控制按鈕
IOS中只有繼承UIResponder類的對象才能處理事件蚓再,比如我們常用的UIView滑肉、UIViewController、
UIApplication摘仅。UIResponder中包含了對三種事件的處理方法靶庙,如果我們需要實現(xiàn)哪種事件的響應(yīng)
邏輯,我們就需要覆蓋這些方法:
觸摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指開始觸摸屏幕時執(zhí)行娃属;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指在屏幕上移動時執(zhí)行六荒,注意此方法在移動過程中會重復(fù)調(diào)用;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指觸摸結(jié)束離開屏幕時執(zhí)行矾端;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 觸摸意外取消時執(zhí)行(例如正在觸摸時打入電話)掏击;
運動事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運動開始時執(zhí)行;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運動結(jié)束后執(zhí)行秩铆;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運動被意外取消時執(zhí)行砚亭;
遠(yuǎn)程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event NS_AVAILABLE_IOS(4_0); 接收到遠(yuǎn)程控制消息時執(zhí)行;
手勢處理
通過覆蓋UIResponder的方法豺旬,我們可以處理觸摸事件钠惩,然而我們在使用iphone的時候,每一個手勢
都是一系列觸摸事件的集合族阅,所以蘋果引入了手勢識別篓跛,并封裝成具體的類,這樣開發(fā)者就不
需要編寫識別算法了坦刀。
UITapGestureRecognizer 點按手勢
UIPinchGestureRecognizer 捏合手勢
UIPanGestureRecognizer 拖動手勢
UISwipeGestureRecognizer 輕掃手勢愧沟,支持四個方向的輕掃,但是不同的方向要分別定義輕掃手勢
UIRotationGestureRecognizer 旋轉(zhuǎn)手勢
UILongPressGestureRecognizer 長按手勢
手勢處理是對觸摸事件的集合鲤遥,其中會有很多中間狀態(tài)沐寺,比如說識別開始、識別中盖奈、識別失敗或者
識別成功等等混坞,所以其實現(xiàn)其實是一個有限狀態(tài)自動機,常用的狀態(tài)有:
UIGestureRecognizerStateBegan //開始
UIGestureRecognizerStateChanged //狀態(tài)變化
UIGestureRecognizerStateEnded //識別結(jié)束=識別成功
每一次狀態(tài)的變更都會導(dǎo)致手勢的響應(yīng)selector被調(diào)用钢坦,所以我們一般在selector中對這幾種
狀態(tài)做區(qū)分處理究孕。
坐標(biāo)轉(zhuǎn)換
在做動畫的時候,可能會需要轉(zhuǎn)換坐標(biāo)系爹凹,比如厨诸,在cell中的button,我們要知道其在整個tableView
中的坐標(biāo)值禾酱,或者是其在屏幕中的位置微酬,我們就需要坐標(biāo)轉(zhuǎn)換绘趋,UIView提供了坐標(biāo)轉(zhuǎn)換的API,
不過我們得小心使用:
// 將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中颗管,返回在目標(biāo)視圖view中的像素值
- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
// 將像素point從view中轉(zhuǎn)換到當(dāng)前視圖中陷遮,返回在當(dāng)前視圖中的像素值
- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
// 將rect由rect所在視圖轉(zhuǎn)換到目標(biāo)視圖view中,返回在目標(biāo)視圖view中的rect
- (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
// 將rect從view中轉(zhuǎn)換到當(dāng)前視圖中垦江,返回在當(dāng)前視圖中的rect
- (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
上述實際上是坐標(biāo)系的轉(zhuǎn)換拷呆,toView是將當(dāng)前坐標(biāo)系中的矩形域轉(zhuǎn)化為view坐標(biāo)系中的矩形域,
而fromView則相反疫粥,將view坐標(biāo)系中的矩形框轉(zhuǎn)化為當(dāng)前坐標(biāo)系中的矩形框。