筆記
Xmind
PPT
1-控制器管理
- 控制器以及view的多種創(chuàng)建方式
- UINavigationController的簡(jiǎn)單使用:添加\移除子控制器
- UINavigationBar內(nèi)容的設(shè)置
- 控制器的生命周期方法
- Segue的使用
- 控制器之間數(shù)據(jù)的傳遞
- UITabBarController的簡(jiǎn)單使用
- UITabBarController和UINavigationController的混合使用
- Modal
2-創(chuàng)建控制器
控制器常見的創(chuàng)建方式有以下幾種
- 直接創(chuàng)建
MJViewController *mj = [[MJViewController alloc] init];
- 指定xib文件來(lái)創(chuàng)建
MJViewController *mj = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];
- 通過(guò)storyboard創(chuàng)建
- 先加載storyboard文件(Test是storyboard的文件名)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
- 接著初始化storyboard中的控制器(兩種方式)
- 初始化“初始控制器”(箭頭所指的控制器)
MJViewController *mj = [storyboard instantiateInitialViewController];
- 通過(guò)一個(gè)標(biāo)識(shí)初始化對(duì)應(yīng)的控制器
MJViewController *mj = [storyboard instantiateViewControllerWithIdentifier:@”mj"];
3-控制器的View
- 控制器view的延遲加載
- 控制器的view是延遲加載的:用到時(shí)再加載
- 可以用isViewLoaded方法判斷一個(gè)UIViewController的view是否已經(jīng)被加載
- 控制器的view加載完畢就會(huì)調(diào)用viewDidLoad方法
4-多控制器的管理
- 一個(gè)iOS的app很少只由一個(gè)控制器組成,除非這個(gè)app極其簡(jiǎn)單
- 當(dāng)app中有多個(gè)控制器的時(shí)候,我們就需要對(duì)這些控制器進(jìn)行管理
- 有多個(gè)view時(shí),可以用一個(gè)大的view去管理1個(gè)或者多個(gè)小view
- 控制器也是如此霉祸,用1個(gè)控制器去管理其他多個(gè)控制器
- 比如筑累,用一個(gè)控制器A去管理3個(gè)控制器B、C丝蹭、D
- 控制器A被稱為控制器B慢宗、C、D的“父控制器”
- 控制器B、C婆廊、D的被稱為控制器A的“子控制器”
- 為了便于管理控制器迅细,iOS提供了2個(gè)比較特殊的控制器
- UINavigationController
- UITabBarController
5-UINavigationController
UINavigationController的view結(jié)構(gòu)
UINavigationController的簡(jiǎn)單使用
- UINavigationController的使用步驟
- 初始化UINavigationController
- 設(shè)置UIWindow的rootViewController為UINavigationController
-
根據(jù)具體情況,通過(guò)push方法添加對(duì)應(yīng)個(gè)數(shù)的子控制器
Snip20170213_200.png
UINavigationController的子控制器
- UINavigationController以棧的形式保存子控制器
- @property(nonatomic,copy) NSArray *viewControllers;
- @property(nonatomic,readonly) NSArray *childViewControllers;
- 使用push方法能將某個(gè)控制器壓入棧
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
- 使用pop方法可以移除控制器
- 將棧頂?shù)目刂破饕瞥?
-(UIViewController *)popViewControllerAnimated:(BOOL)animated;
- 回到指定的子控制器
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
- 回到根控制器(棧底控制器)
-(NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
###如何修改導(dǎo)航欄的內(nèi)容
- 導(dǎo)航欄的內(nèi)容由棧頂控制器的navigationItem屬性決定
- UINavigationItem有以下屬性影響著導(dǎo)航欄的內(nèi)容
- 左上角的返回按鈕
@property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;
- 中間的標(biāo)題視圖
@property(nonatomic,retain) UIView *titleView;
- 中間的標(biāo)題文字
@property(nonatomic,copy) NSString *title;
- 左上角的視圖
@property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
UIBarButtonItem *rightBarButtonItem 右上角的視圖
@property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;
##6-Segue
- Storyboard上每一根用來(lái)界面跳轉(zhuǎn)的線淘邻,都是一個(gè)UIStoryboardSegue對(duì)象(簡(jiǎn)稱Segue)

###Segue的屬性
- 每一個(gè)Segue對(duì)象茵典,都有3個(gè)屬性
- 唯一標(biāo)識(shí)
@property (nonatomic, readonly) NSString *identifier;
- 來(lái)源控制器
@property (nonatomic, readonly) id sourceViewController;
- 目標(biāo)控制器
@property (nonatomic, readonly) id destinationViewController;

###Segue的類型
- 根據(jù)Segue的執(zhí)行(跳轉(zhuǎn))時(shí)刻,Segue可以分為2大類型
- 自動(dòng)型:點(diǎn)擊某個(gè)控件后(比如按鈕)宾舅,自動(dòng)執(zhí)行Segue统阿,自動(dòng)完成界面跳轉(zhuǎn)
- 手動(dòng)型:需要通過(guò)寫代碼手動(dòng)執(zhí)行Segue,才能完成界面跳轉(zhuǎn)
###自動(dòng)型Segue
- 按住Control鍵筹我,直接從控件拖線到目標(biāo)控制器

- 點(diǎn)擊“登錄”按鈕后扶平,就會(huì)自動(dòng)跳轉(zhuǎn)到右邊的控制器
- 如果點(diǎn)擊某個(gè)控件后,不需要做任何判斷蔬蕊,一定要跳轉(zhuǎn)到下一個(gè)界面结澄,建議使用“自動(dòng)型Segue”
###手動(dòng)型Segue
- 按住Control鍵,從來(lái)源控制器拖線到目標(biāo)控制器

- 在恰當(dāng)?shù)臅r(shí)刻岸夯,使用perform方法執(zhí)行對(duì)應(yīng)的Segue
[self performSegueWithIdentifier:@"login2contacts" sender:nil];
// Segue必須由來(lái)源控制器來(lái)執(zhí)行麻献,也就是說(shuō),這個(gè)perform方法必須由來(lái)源控制器來(lái)調(diào)用
- 如果點(diǎn)擊某個(gè)控件后猜扮,需要做一些判斷勉吻,也就是說(shuō):滿足一定條件后才跳轉(zhuǎn)到下一個(gè)界面,建議使用“手動(dòng)型Segue”
###performSegueWithIdentifier:sender:方法
- 利用performSegueWithIdentifier:方法可以執(zhí)行某個(gè)Segue旅赢,完成界面跳轉(zhuǎn)
- 接下來(lái)研究performSegueWithIdentifier:sender:方法的完整執(zhí)行過(guò)程
[self performSegueWithIdentifier:@“l(fā)ogin2contacts” sender:nil];
// 這個(gè)self是來(lái)源控制器
- 根據(jù)identifier去storyboard中找到對(duì)應(yīng)的線齿桃,新建UIStoryboardSegue對(duì)象
- 設(shè)置Segue對(duì)象的sourceViewController(來(lái)源控制器)
- 新建并且設(shè)置Segue對(duì)象的destinationViewController(目標(biāo)控制器)

- 調(diào)用sourceViewController的下面方法,做一些跳轉(zhuǎn)前的準(zhǔn)備工作并且傳入創(chuàng)建好的Segue對(duì)象
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
// 這個(gè)sender是當(dāng)初performSegueWithIdentifier:sender:中傳入的sender
- 調(diào)用Segue對(duì)象的- (void)perform;方法開始執(zhí)行界面跳轉(zhuǎn)操作
- 如果segue的style是push
- 取得sourceViewController所在的UINavigationController
- 調(diào)用UINavigationController的push方法將destinationViewController壓入棧中煮盼,完成跳轉(zhuǎn)
- 如果segue的style是modal
- 調(diào)用sourceViewController的presentViewController方法將destinationViewController展示出來(lái)
###Sender參數(shù)的傳遞
[self performSegueWithIdentifier:@“l(fā)ogin2contacts” sender:@“jack”];
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
##7-控制器的數(shù)據(jù)傳遞
- 控制器之間的數(shù)據(jù)傳遞主要有2種情況:順傳和逆?zhèn)? - 順傳
- 控制器的跳轉(zhuǎn)方向: A->C
- 數(shù)據(jù)的傳遞方向 : A -> C
- 數(shù)據(jù)的傳遞方式 : 在A的prepareForSegue:sender:方法中根據(jù)segue參數(shù)取得destinationViewController, 也就是控制器C, 直接給控制器C傳遞數(shù)據(jù)
(要在C的viewDidLoad方法中取得數(shù)據(jù),來(lái)賦值給界面上的UI控件)

- 逆?zhèn)? - 控制器的跳轉(zhuǎn)方向: A ->C
- 數(shù)據(jù)的傳遞方向 : C ->A
- 數(shù)據(jù)的傳遞方式 : 讓A成為C的代理, 在C中調(diào)用A的代理方法,通過(guò)代理方法的參數(shù)傳遞數(shù)據(jù)給A

##8-UITabBarController
###UITabBarController的簡(jiǎn)單使用
- UITabBarController的使用步驟
- 初始化UITabBarController
- 設(shè)置UIWindow的rootViewController為UITabBarController
- 根據(jù)具體情況短纵,通過(guò)addChildViewController方法添加對(duì)應(yīng)個(gè)數(shù)的子控制器
###UITabBarController的子控制器
- UITabBarController添加控制器的方式有2種
- 添加單個(gè)子控制器
- (void)addChildViewController:(UIViewController *)childController;
- 設(shè)置子控制器數(shù)組
@property(nonatomic,copy) NSArray *viewControllers;
###UITabBarController的view結(jié)構(gòu)


###UITabBar
- 如果UITabBarController有N個(gè)子控制器,那么UITabBar內(nèi)部就會(huì)有N個(gè)UITabBarButton作為子控件
- 如果UITabBarController有4個(gè)子控制器僵控,那么UITabBar的結(jié)構(gòu)大致如下圖所示

###UITabBarButton

###App主流UI框架結(jié)構(gòu)

###Modal
- 除了push之外踩娘,還有另外一種控制器的切換方式,那就是Modal
- 任何控制器都能通過(guò)Modal的形式展示出來(lái)
- Modal的默認(rèn)效果:新控制器從屏幕的最底部往上鉆喉祭,直到蓋住之前的控制器為止
- 以Modal的形式展示控制器
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
- 關(guān)閉當(dāng)初Modal出來(lái)的控制器
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;

###9-圖片



#總結(jié)
1.loadView方法作用以及注意點(diǎn)有哪些?
作用:控制器會(huì)調(diào)用方法去創(chuàng)建控制器的View.
什么時(shí)候調(diào)用:當(dāng)?shù)谝淮问褂每刂破鞯腣iew
開發(fā)中l(wèi)oadView使用場(chǎng)景:自定義控制器的View.
1.一旦重寫了loadView,表示需要自己創(chuàng)建控制器的View.
2.如果控制器的View還沒有賦值,就不能調(diào)用控制器View的get方法.會(huì)造成死循環(huán).因?yàn)榭刂破鱒iew的get方法底層會(huì)調(diào)用loadView方法.
2.KVC底層實(shí)現(xiàn)?
setValue:obj forKeyPath:key的底層實(shí)現(xiàn):
1.它會(huì)調(diào)用這個(gè)屬性的set方法.
2.如果沒有set方法,它會(huì)去判斷有沒有跟key值同名的成員屬性.如果有,就直接賦值.icon = obj.
3.如果沒有,那么它還會(huì)去判斷有沒有跟key值名相同帶有下劃線的成員屬性,如果有,就直接賦值,_icon = obj.
4.如果都沒有, 就直接報(bào)錯(cuò).找不到對(duì)應(yīng)的成員屬性.
3.控制器View懶加載是什么意思?
什么時(shí)候用到控制器View的時(shí)候,才會(huì)調(diào)用loadView方法創(chuàng)建控制器的View
4.導(dǎo)航控制器管理原則?
1.當(dāng)調(diào)用導(dǎo)航控制器的push方法時(shí), 就會(huì)把一個(gè)控制器壓入到導(dǎo)航控制器的棧中, 那么剛壓入棧中的這個(gè)導(dǎo)航控制器就在棧的最頂部.
2.它就會(huì)把原來(lái)導(dǎo)航控制器View當(dāng)中存放的子控制器View的內(nèi)容移除,然后把導(dǎo)航控制器棧頂控制器的View添加到導(dǎo)航控制器專門存放子控制器View當(dāng)中.
3.注意:只是把控制器的View從導(dǎo)航控制器存放子控制器的View當(dāng)中移除,并沒有把控制器從棧中移除.所以上一個(gè)控制器還在.
4.當(dāng)調(diào)用pop當(dāng)方法時(shí), 就會(huì)把導(dǎo)航控制器存放子控制器View當(dāng)中控制器的View移除,并且會(huì)把該控制器從棧里面移除.
5.此時(shí)該控制器就會(huì)被銷毀.接著它就會(huì)把上一個(gè)控制器的View添加到導(dǎo)航控制器專門存放子控制器的View當(dāng)中.
5.如果設(shè)置導(dǎo)航條內(nèi)容?
設(shè)置導(dǎo)航條的內(nèi)容,由棧頂控制器的NavgationItem決定.
6.事件是怎么樣產(chǎn)生與傳遞的?
1.當(dāng)發(fā)生一個(gè)觸摸事件后,系統(tǒng)會(huì)將該事件加入到一個(gè)由UIApplication管理的事件隊(duì)列中.
2.UIApplication會(huì)從事件隊(duì)列中取出最前面的事件养渴,將事件傳遞給主窗口
3.主窗口會(huì)在視圖層次結(jié)構(gòu)中找到一個(gè)最合適的視圖來(lái)處理觸摸事件
4.觸摸事件的傳遞是從父控件傳遞到子控件的.
5.如果一個(gè)父控件不能接收事件,那么它里面的了子控件也不能夠接收事件.
7.一個(gè)控件什么情況下不能夠接收事件?
1.不接收用戶交互時(shí)不能夠處理事件:userInteractionEnabled = NO
2.當(dāng)一個(gè)控件隱藏的時(shí)候不能夠接收事件:Hidden = YES的時(shí)候
3.當(dāng)一個(gè)控件為透明白時(shí)候也不能夠接收事件:alpha <= 0.01
8.如果尋找最適合的View?
1.先判斷自己是否能夠接收觸摸事件,如果能再繼續(xù)往下判斷,
2.再判斷觸摸的當(dāng)前點(diǎn)在不在自己的身上.
3.如果在自己身上,它會(huì)從后往前遍歷子控件,遍歷出每一個(gè)子控件后,重復(fù)前面的兩個(gè)步驟.
4.如果沒有符合條件的子控件,那么它自己就是最適合的View.
9.事件傳遞與響應(yīng)的完整過(guò)程是什么?
1.先將事件對(duì)象由上往下傳遞(由父控件傳遞給子控件),找到最合適的控件來(lái)處理這個(gè)事件泛烙。
2.調(diào)用最合適控件的touches….方法
3.如果調(diào)用了[super touches….];就會(huì)將事件順著響應(yīng)者鏈條往上傳遞理卑,傳遞給上一個(gè)響應(yīng)者
4.接著就會(huì)調(diào)用上一個(gè)響應(yīng)者的touches….方法
10.如何判斷上一個(gè)響應(yīng)者
1.如果當(dāng)前這個(gè)view是控制器的view,那么控制器就是上一個(gè)響應(yīng)者
2.如果當(dāng)前這個(gè)view不是控制器的view,那么父控件就是上一個(gè)響應(yīng)者
11.UIApplication作用?
1.設(shè)置應(yīng)用提醒數(shù)字
2.設(shè)置連網(wǎng)狀態(tài)
3.設(shè)置狀態(tài)欄
4.跳轉(zhuǎn)網(wǎng)頁(yè)
12.應(yīng)用程序的程動(dòng)原理
1.執(zhí)行Main
2.執(zhí)行UIApplicationMain函數(shù).
3.創(chuàng)建UIApplication對(duì)象,并設(shè)置UIApplicationMain對(duì)象的代理.
4.開啟一個(gè)主運(yùn)行循環(huán).保證應(yīng)用程序不退出.
5.加載info.plist.加載配置文件.判斷一下info.plist文件當(dāng)中有沒有Main storyboard file base name,里面有沒有指定storyboard文件,
13.如何創(chuàng)建UIWindow?
1.創(chuàng)建窗口
2.創(chuàng)建控制器
3.設(shè)置控制器為窗口的根控制器
4.顯示窗口
14.push與show的區(qū)別(push與show方法只有在有導(dǎo)航控制器下才有效)
1.push這個(gè)方法過(guò)期了,通過(guò)StoryBoard跳轉(zhuǎn)控制器蔽氨,從一個(gè)控制器的界面按住ctrl拖向下一個(gè)控制器藐唠,運(yùn)行時(shí)可以從當(dāng)前控制器跳轉(zhuǎn)到下一個(gè)控制器帆疟。
2.show方法也是一樣,功能相同但他是個(gè)新方法宇立,在iphone設(shè)備上show顯示的是一個(gè)控制器窗口踪宠,但在ipad的上顯示的是兩個(gè)窗口,一個(gè)正常窗口一個(gè)是詳情頁(yè)窗口妈嘹。
3.-viewDidLoad方法在view的整個(gè)生命周期中只會(huì)調(diào)用一次柳琢,所以在這個(gè)方法里面可以加載子控件和加載網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求
4.-viewWillAppear和-viewWillDisAppear方法里面設(shè)置view即將顯示時(shí)和即將消失時(shí)需要設(shè)置的操作,這兩個(gè)方法多次調(diào)用