在使用微信查看聯(lián)系人頭像的時(shí)候,可以點(diǎn)擊頭像使之放大、進(jìn)而填充整個(gè)window,可以對(duì)大圖
進(jìn)行雙擊、縮放、平移等操作,總的來(lái)說(shuō)這個(gè)過(guò)程的編碼也不復(fù)雜,但是涉及到UIWindow、手勢(shì)
識(shí)別方面的知識(shí),有必要總結(jié)一下。
UIWindow
UIWindow是一種特殊的UIView,我們一般在程序中這樣來(lái)指定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;
}
一個(gè)App中通常只有一個(gè)UIWindow,作為所有視圖的容器。在編碼的過(guò)程中這樣來(lái)獲得App的keyWindow:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
當(dāng)然,我們也可以手動(dòng)創(chuàng)建多個(gè)UIWindow,多個(gè)Window的顯示順序是根據(jù)UIWindowLevel進(jìn)行排序的,
IOS默認(rèn)定義了三個(gè)等級(jí):
const UIWindowLevel UIWindowLevelNormal; //0.0
const UIWindowLevel UIWindowLevelAlert; //2000.0
const UIWindowLevel UIWindowLevelStatusBar; //1000.0
值得注意的是:UIWindow是嚴(yán)格按照Level來(lái)顯示的,與keyWindow的設(shè)置順序無(wú)關(guān),在使用的
過(guò)程中常用的場(chǎng)景是需要全屏幕覆蓋一個(gè)蒙層。
事件處理
任何一款移動(dòng)設(shè)備都會(huì)有事件處理,允許操作系統(tǒng)能夠?qū)τ脩舻牟僮鬟M(jìn)行響應(yīng),IOS中的用戶事件
分為三種:
1. 觸摸事件:通過(guò)觸摸、手勢(shì)進(jìn)行觸發(fā)
2. 運(yùn)動(dòng)事件:通過(guò)加速器進(jìn)行觸發(fā),例如手機(jī)晃動(dòng)
3. 遠(yuǎn)程控制事件:遠(yuǎn)程設(shè)備觸發(fā),例如耳機(jī)控制按鈕
IOS中只有繼承UIResponder類的對(duì)象才能處理事件,比如我們常用的UIView、UIViewController、
UIApplication。UIResponder中包含了對(duì)三種事件的處理方法,如果我們需要實(shí)現(xiàn)哪種事件的響應(yīng)
邏輯,我們就需要覆蓋這些方法:
觸摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指開(kāi)始觸摸屏幕時(shí)執(zhí)行;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指在屏幕上移動(dòng)時(shí)執(zhí)行,注意此方法在移動(dòng)過(guò)程中會(huì)重復(fù)調(diào)用;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 一根或多根手指觸摸結(jié)束離開(kāi)屏幕時(shí)執(zhí)行;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 觸摸意外取消時(shí)執(zhí)行(例如正在觸摸時(shí)打入電話);
運(yùn)動(dòng)事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運(yùn)動(dòng)開(kāi)始時(shí)執(zhí)行;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運(yùn)動(dòng)結(jié)束后執(zhí)行;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event NS_AVAILABLE_IOS(3_0); 運(yùn)動(dòng)被意外取消時(shí)執(zhí)行;
遠(yuǎn)程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event NS_AVAILABLE_IOS(4_0); 接收到遠(yuǎn)程控制消息時(shí)執(zhí)行;
手勢(shì)處理
通過(guò)覆蓋UIResponder的方法,我們可以處理觸摸事件,然而我們?cè)谑褂胕phone的時(shí)候,每一個(gè)手勢(shì)
都是一系列觸摸事件的集合,所以蘋果引入了手勢(shì)識(shí)別,并封裝成具體的類,這樣開(kāi)發(fā)者就不
需要編寫識(shí)別算法了。
UITapGestureRecognizer 點(diǎn)按手勢(shì)
UIPinchGestureRecognizer 捏合手勢(shì)
UIPanGestureRecognizer 拖動(dòng)手勢(shì)
UISwipeGestureRecognizer 輕掃手勢(shì),支持四個(gè)方向的輕掃,但是不同的方向要分別定義輕掃手勢(shì)
UIRotationGestureRecognizer 旋轉(zhuǎn)手勢(shì)
UILongPressGestureRecognizer 長(zhǎng)按手勢(shì)
手勢(shì)處理是對(duì)觸摸事件的集合,其中會(huì)有很多中間狀態(tài),比如說(shuō)識(shí)別開(kāi)始、識(shí)別中、識(shí)別失敗或者
識(shí)別成功等等,所以其實(shí)現(xiàn)其實(shí)是一個(gè)有限狀態(tài)自動(dòng)機(jī),常用的狀態(tài)有:
UIGestureRecognizerStateBegan //開(kāi)始
UIGestureRecognizerStateChanged //狀態(tài)變化
UIGestureRecognizerStateEnded //識(shí)別結(jié)束=識(shí)別成功
每一次狀態(tài)的變更都會(huì)導(dǎo)致手勢(shì)的響應(yīng)selector被調(diào)用,所以我們一般在selector中對(duì)這幾種
狀態(tài)做區(qū)分處理。
坐標(biāo)轉(zhuǎn)換
在做動(dòng)畫的時(shí)候,可能會(huì)需要轉(zhuǎn)換坐標(biāo)系,比如,在cell中的button,我們要知道其在整個(gè)tableView
中的坐標(biāo)值,或者是其在屏幕中的位置,我們就需要坐標(biāo)轉(zhuǎn)換,UIView提供了坐標(biāo)轉(zhuǎn)換的API,
不過(guò)我們得小心使用:
// 將像素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;
上述實(shí)際上是坐標(biāo)系的轉(zhuǎn)換,toView是將當(dāng)前坐標(biāo)系中的矩形域轉(zhuǎn)化為view坐標(biāo)系中的矩形域,
而fromView則相反,將view坐標(biāo)系中的矩形框轉(zhuǎn)化為當(dāng)前坐標(biāo)系中的矩形框。