UI控件進(jìn)階2——多控制器管理


控制器及View的多種創(chuàng)建方式

  • 創(chuàng)建控制器的3種方式端圈?
    1. 直接通過alloc + init的方式創(chuàng)建蒲拉。
      • 創(chuàng)建一個(gè)“Single View Application”驰徊,刪除默認(rèn)控制器他膳、Main.storyboard、Main Interface設(shè)置為空望蜡。
      • 創(chuàng)意一個(gè)自定義的控制器唤崭,F(xiàn)irstViewController。
      • 在AppDelegate的application:didFinishLaunchingWithOptions:方法中創(chuàng)建UIWindow對象脖律。
      • 通過alloc + init的方式創(chuàng)建該控制器的對象谢肾,并設(shè)置該控制器view的背景色。
      • 設(shè)置UIWindow的根控制器為該控制器對象小泉。
    2. 通過加載storyboard文件來創(chuàng)建一個(gè)控制器芦疏。
      • 刪除了Main.storyboard文件,也清空了Main Interface的配置膏孟,那么現(xiàn)在就需要自己創(chuàng)建一個(gè)新的storyboard文件(Two.storyboard), 然后拖一個(gè)控制器上去眯分,在AppDelegate中自己寫代碼來加載Two.storyboard文件。
    3. 通過指定的xib文件來創(chuàng)建控制器柒桑。
      • 創(chuàng)建一個(gè)自己的控制器類弊决。
      • 創(chuàng)建一個(gè)xib文件,在xib文件中拽一個(gè)UIView。
      • 選中xib文件中的“File's Owner”飘诗,在屬性中設(shè)置對應(yīng)的類(Class)是剛才創(chuàng)建的控制器類与倡。“File's Owner”可以理解為昆稿,當(dāng)前xib文件是為誰服務(wù)的纺座。
      • 然后選中“File's Owner”->“右擊”選中“view”->拖線到對應(yīng)的view上。(設(shè)置該xib文件中哪個(gè)視圖是控制器默認(rèn)要?jiǎng)?chuàng)建的視圖)
      • 通過alloc + initWithNibName來創(chuàng)建溉潭。
// 一净响、直接通過alloc+init的方式創(chuàng)建
// 1.創(chuàng)建UIWindow
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 2.創(chuàng)建控制器 
FirstViewController *vc1 = [[FirstViewController alloc] init];
vc1.view.backgroundColor = [UIColor blueColor];
// 3.設(shè)置控制器為UIWindow對象的根控器"rootViewController"                            
self.window.rootViewController = vc1;
// 4.顯示UIWindow對象
[self.window makeKeyAndVisible];

// 二、通過加載storyboard文件創(chuàng)建
// 1.加載對應(yīng)的storyboard文件
UIStoryboard *myStoryboard = [UIStoryboard storyboardWithName:@"My" bundle:nil];
// 2.創(chuàng)建該storyboard中的被設(shè)置為"初始化控制器"(箭頭所指向的控制器)的對象喳瓣。
UIViewController *vc2 = [myStoryboard instantiateInitialViewController];
// 3.根據(jù)storyboard中的控制器的storyboard ID來創(chuàng)建對應(yīng)的控制器
UIViewController *vc3 = [myStoryboard instantiateViewControllerWithIdentifier:@"redVwController"];
// 4.設(shè)置控制器為UIWindow對象的根控制器"rootViewController"
self.window.rootViewController = vc2;

// 三馋贤、通過指定的 xib 文件來創(chuàng)建
// 1.通過xib文件, 創(chuàng)建控制器
FirstViewController *vc1 = [[FirstViewController alloc] initWithNibName:@"First" bundle:nil];
// 2.設(shè)置控制器為UIWindow對象的根控制器"rootViewController"
self.window.rootViewController = vc1;

  • 創(chuàng)建控制器中的UIView?
    1. 控制器創(chuàng)建好以后畏陕,控制器所管理的view是如何創(chuàng)建的配乓?
      • 控制器的view是通過調(diào)用控制器的loadView方法來創(chuàng)建的。這個(gè)方法是UIViewController中的一個(gè)對象方法惠毁,只要控制器的loadView方法被調(diào)用了犹芹,那么證明控制器的view創(chuàng)建好了。
      • 當(dāng)調(diào)用完畢控制器的loadView方法以后鞠绰,從這時(shí)開始腰埂,才創(chuàng)建好了控制器的view。
      • 當(dāng)控制器的view被創(chuàng)建好以后洞豁,緊接著就調(diào)用控制器的viewDidLoad方法盐固。
      • 控制器的view采用了懶加載的方式荒给,也就是說丈挟,在需要的時(shí)候(在用到的時(shí)候)才會(huì)創(chuàng)建(調(diào)用loadView方法)。
      • 注意:無論控制器是如何創(chuàng)建的志电,只要在控制器中曙咽,重寫了loadView方法,并且沒有調(diào)用[super loadView];方法挑辆,那么最終控制器的view就必須完全在loadView方法中自己來創(chuàng)建了例朱,所以loadView方法可以用來自定義view。
    2. 控制器中的view創(chuàng)建:當(dāng)?shù)谝淮螐膕elf.view中獲取view的時(shí)候(第一次使用self.view的時(shí)候)鱼蝉,控制器會(huì)調(diào)用它自己的loadView方法先創(chuàng)建一個(gè)view洒嗤,并且把這個(gè)新創(chuàng)建的view設(shè)置給self.view。
      • 如果是直接通過alloc + init方法創(chuàng)建的控制器魁亦,則self.view = [[UIView alloc] init];渔隶。
      • 如果是通過storyboard創(chuàng)建的控制器,加載storyboard中的控制器,并把storyboard中的控制器中的view設(shè)置給self.view间唉。
      • 如果是通過加載xib創(chuàng)建的控制器绞灼,加載xib中的view,并把xib中的view設(shè)置給self.view呈野。
    3. 通過storyboard創(chuàng)建完控制器后低矮,自動(dòng)調(diào)用loadView方法,創(chuàng)建控制器的view被冒。此時(shí)自定義的控制器军掂,因?yàn)闆]有“重寫”loadView方法,所以loadView方法內(nèi)部就是根據(jù)storyboard文件中的view來創(chuàng)建view的昨悼。
    4. 通過xib文件創(chuàng)建完控制器后良姆,自動(dòng)調(diào)用loadView創(chuàng)建控制器的view。此時(shí)自定義的控制器幔戏,因?yàn)闆]有“重寫”loadView方法玛追,所以loadView方法內(nèi)部就是根據(jù)xib文件中的view來創(chuàng)建view的。
      • 如果創(chuàng)建控制器的時(shí)候闲延,通過initWithNibName指定了xib的名字痊剖,那么就根據(jù)該xib創(chuàng)建view。
      • 如果創(chuàng)建控制器的時(shí)候垒玲,沒有指定任何xib文件陆馁,也沒有相應(yīng)的storyboard文件,那么會(huì)嘗試查找“與控制器名字相同的合愈,但是去除Controller的文件名的xib文件”叮贩,如果還是沒有,會(huì)嘗試查找與控制器名字完全相同的xib文件佛析,如果有益老,則使用該xib文件創(chuàng)建view。
      • 建議:如果要使用某個(gè)xib文件名自動(dòng)匹配的方式創(chuàng)建view寸莫,建議名字與控制器相同捺萌。
    5. 通過重寫UIViewController的loadView方法,自己通過代碼來創(chuàng)建控制器的view膘茎。
      • 控制器的loadView方法就是用來自定義view的桃纯。如果要為控制器自定義view,要寫在loadView中披坏,不要寫在viewDidLoad中态坦。
      • 如果重寫loadView方法中調(diào)用了[super loadView];,那么依然會(huì)使用默認(rèn)的方式來加載棒拂。想自定義伞梯,應(yīng)該不調(diào)用此方法。
    6. 無論是通過加載xib創(chuàng)建view,storyboard創(chuàng)建view壮锻,最終都依賴于loadView方法琐旁。
    7. 控制器的loadView方法什么時(shí)候調(diào)用?
      • 在需要用到控制器的view的時(shí)候才調(diào)用猜绣,當(dāng)調(diào)用UIWindow對象的makeKeyAndVisible方法時(shí)灰殴,就需要顯示該view了,此時(shí)就表示用到view了掰邢,這個(gè)就叫做“延遲加載”牺陶。

多控制器管理

  • 多控制器管理?
    1. 多控制器管理的思路:使用一個(gè)控制器來管理所有其他控制器辣之,類似于使用一個(gè)UIView來管理其他的子view掰伸。
    2. 父控制器:管理其他控制器的控制器,就可以看做是“父控制器”怀估、子控制器:被管理的控制器就是子控制器狮鸭。
    3. iOS提供了兩個(gè)比較特殊的控制器(用來管理“控制器”的控制器):
      • UINavigationController導(dǎo)航控制器,輕松管理多個(gè)控制器多搀,并且控制不同控制器之間的跳轉(zhuǎn)和切換歧蕉。
      • UITabBarController也可以輕松地管理多個(gè)控制器,輕松完成控制器之間的切換康铭。

  • UINavigationController導(dǎo)航控制器惯退?
    1. 使用步驟:
      • 創(chuàng)建、初始化一個(gè)導(dǎo)航控制器:UINavigationController从藤。
      • 設(shè)置UIWindow的rootController為UINavigationController催跪。
      • 通過調(diào)用push方法添加子控制器到UINavigationController。
      • 通過pop方法可以返回到上一個(gè)控制器夷野。
      • 注意:誰是最后一個(gè)push進(jìn)來的懊蒸,當(dāng)前顯示的就是哪個(gè)viewController。
    2. 導(dǎo)航控制器的導(dǎo)航欄是從Y坐標(biāo)20開始的扫责,高度是44榛鼎,導(dǎo)航欄上面的20高度是“狀態(tài)欄”逃呼。導(dǎo)航欄的內(nèi)容由棧頂控制器的navigationItem屬性決定鳖孤。
    3. UINavigationController導(dǎo)航控制器以棧的形式保存的子控制器。
@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;

// 左上角的返回按鈕
@property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;
// 中間的標(biāo)題視圖
@property(nonatomic,retain) UIView *titleView;
// 中間的標(biāo)題文字
@property(nonatomic,copy) NSString *title;
// 左上角的按鈕
@property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
// 右上角的按鈕
@property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;

  • UITabBarController抡笼?
    1. 使用步驟:
      • 初始化UITabBarController苏揣。
      • 設(shè)置UIWindow的rootViewController為UITabBarController。
      • 根據(jù)具體情況推姻,通過addChildViewController方法添加對應(yīng)個(gè)數(shù)的子控制器平匈。
    2. 如果UITabBarController有N個(gè)子控制器,那么UITabBar內(nèi)部就會(huì)有N個(gè)UITabBarButton作為子控件。
// 添加單個(gè)子控制器
- (void)addChildViewController:(UIViewController *)childController;
// 設(shè)置子控制器數(shù)組
@property (nonatomic,copy) NSArray *viewControllers;
// 標(biāo)題文字
@property(nonatomic,copy) NSString *title;
// 圖標(biāo)
@property(nonatomic,retain) UIImage *image;
// 選中時(shí)的圖標(biāo)
@property(nonatomic,retain) UIImage *selectedImage;
// 提醒數(shù)字
@property(nonatomic,copy) NSString *badgeValue;


  • App主流UI框架結(jié)構(gòu)增炭?
App主流UI框架結(jié)構(gòu)

  • Segue的介紹忍燥?
    1. storyboard上每一根用來界面跳轉(zhuǎn)的線,都是一個(gè)UIStoryboardSegue對象隙姿,簡稱Segue梅垄,表示延續(xù)都弹、繼續(xù)的意思析命。
    2. 每一個(gè)segue對象,都有3個(gè)屬性:①唯一標(biāo)識腹缩;②來源控制器欲鹏;③目標(biāo)控制器机久。
    3. 根據(jù)segue的執(zhí)行(跳轉(zhuǎn))時(shí)刻,segue可以分為2大類型:
      • 自動(dòng)型:點(diǎn)擊某個(gè)控件后赔嚎,自動(dòng)執(zhí)行segue膘盖,自動(dòng)完成界面跳轉(zhuǎn)。
      • 手動(dòng)型:需要通過寫代碼手動(dòng)執(zhí)行segue尤误,才能完成界面跳轉(zhuǎn)衔憨。
    4. 自動(dòng)型segue:
      • 按住control鍵,直接從控件拖線到目標(biāo)控制器袄膏。
      • 如果點(diǎn)擊某個(gè)控件践图,不需要做任何判斷,直接跳轉(zhuǎn)到下一個(gè)界面沉馆,建議使用“自動(dòng)型segue”码党。
    5. 手動(dòng)型segue:
      • 按住control鍵,從來源控制器拖線到目標(biāo)控制器斥黑。
      • 手動(dòng)型的segue需要設(shè)置一個(gè)標(biāo)識Identifier揖盘。
      • 如果點(diǎn)擊某個(gè)控件,需要做一些處理之后才能跳轉(zhuǎn)到下一個(gè)界面锌奴,建議使用“手動(dòng)型segue”兽狭。
    6. 利用某個(gè)控制器的performSegueWithIdentifier:對象方法可以執(zhí)行當(dāng)前控制器的某個(gè)Segue,跳轉(zhuǎn)界面:
      • self是來源控制器鹿蜀,只能通過來源控制器來調(diào)用該方法箕慧。
      • 根據(jù)Identifier去storyboard中找到對應(yīng)的線,新建UIStoryboardSegue對象茴恰。
      • 設(shè)置Segue對象的sourceViewController(來源控制器)颠焦。
      • 新建并且設(shè)置Segue對象的destinationViewController(目標(biāo)控制器)。
    7. 調(diào)用sourceViewController來源控制器的- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;方法往枣,做跳轉(zhuǎn)前的準(zhǔn)備工作并傳入創(chuàng)建好的Segue對象伐庭。
      • sender就是調(diào)用performSegueWithIdentifier:sender:方法時(shí)傳入的對象粉渠。
      • 調(diào)用Segue對象的- (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展示出來淳衙。

  • Modal介紹?
    1. 除了push之外饺著,還有另一種控制器的切換方式箫攀,那就是Modal,任何控制器都能通過modal的形式展示出來幼衰。
    2. modal的默認(rèn)效果:新控制器從屏幕的最底部往上鉆靴跛,直到蓋住之前的控制器為止。
// 以modal的形式展示控制器
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion;
// 關(guān)閉當(dāng)初modal出來的控制器
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;

  • 控制器的數(shù)據(jù)傳遞
    1. 順傳:
      • 控制器的跳轉(zhuǎn)方向:A->B渡嚣。
      • 數(shù)據(jù)的傳遞方向:A->B梢睛。
      • 數(shù)據(jù)的傳遞方式:在A控制器的prepareForSegue:sender:方法中根據(jù)Segue參數(shù)取得destinationViewController,也就是控制器B识椰,直接給控制器B傳遞數(shù)據(jù)绝葡。
      • 在B的viewDidLoad方法中取得數(shù)據(jù),或者利用setter方法腹鹉,設(shè)置界面上的UI控件藏畅。
        控制器的數(shù)據(jù)傳遞(順傳)
    2. 逆?zhèn)鳎?
      • 控制器的跳轉(zhuǎn)方向:A->B。
      • 數(shù)據(jù)的傳遞方向:B->A功咒。
      • 數(shù)據(jù)的傳遞方式:讓A成為B的代理愉阎,在B中調(diào)用A的代理方法,通過代理方法的參數(shù)傳遞數(shù)據(jù)給A力奋。


        控制器的數(shù)據(jù)傳遞(逆?zhèn)?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末榜旦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子景殷,更是在濱河造成了極大的恐慌溅呢,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猿挚,死亡現(xiàn)場離奇詭異咐旧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)亭饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門休偶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辜羊,你說我怎么就攤上這事踏兜。” “怎么了八秃?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵碱妆,是天一觀的道長。 經(jīng)常有香客問我昔驱,道長疹尾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任骤肛,我火速辦了婚禮纳本,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘腋颠。我一直安慰自己繁成,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布淑玫。 她就那樣靜靜地躺著巾腕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪絮蒿。 梳的紋絲不亂的頭發(fā)上尊搬,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音土涝,去河邊找鬼佛寿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛但壮,可吹牛的內(nèi)容都是我干的狗准。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼茵肃,長吁一口氣:“原來是場噩夢啊……” “哼腔长!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起验残,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤捞附,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后您没,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸟召,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年氨鹏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了欧募。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仆抵,死狀恐怖跟继,靈堂內(nèi)的尸體忽然破棺而出种冬,到底是詐尸還是另有隱情,我是刑警寧澤舔糖,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布娱两,位于F島的核電站,受9級特大地震影響金吗,放射性物質(zhì)發(fā)生泄漏十兢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一摇庙、第九天 我趴在偏房一處隱蔽的房頂上張望旱物。 院中可真熱鬧,春花似錦卫袒、人聲如沸宵呛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烤蜕。三九已至,卻和暖如春迹冤,著一層夾襖步出監(jiān)牢的瞬間讽营,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工泡徙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留橱鹏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓堪藐,卻偏偏與公主長得像莉兰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子礁竞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容