UINavigationController

多控制器

  1. 當(dāng)app中有多個控制器的時候,我們就需要對這些控制器進(jìn)行管理枚荣,思路是用1個控制器去管理其他多個控制器罚攀,成為控制器的控制器吹榴,稱其為父控制器
  • 為了便于管理控制器肌厨,iOS提供了2個比較特殊的控制器
    1. UINavigationController
    2. UITabBarController

UINavigationController

  1. 父類是UIViewController

導(dǎo)航控制器與子控制器

1. 導(dǎo)航條的內(nèi)容由棧頂控制器決定,一個導(dǎo)航控制器只有一個導(dǎo)航條,因此只能由一個控制器決定,誰先顯示在最外面,誰就是棧頂控制器.
2. 導(dǎo)航控制器永遠(yuǎn)顯示的是棧頂控制器的view
3. 導(dǎo)航控制器中做界面之間的跳轉(zhuǎn)必須拿到導(dǎo)航控制器,導(dǎo)航控制器的子控制器可以直接拿到導(dǎo)航控制器
4. 調(diào)用pop方法并不會馬上銷毀當(dāng)前控制器
5. popToViewController使用注意點(diǎn),傳入進(jìn)去的控制器必須是導(dǎo)航控制器棧里面的控制器

導(dǎo)航控制器的結(jié)構(gòu)

  1. 導(dǎo)航控制器內(nèi)部結(jié)構(gòu)(UINavigationBar(導(dǎo)航條),導(dǎo)航控制器的view,存放導(dǎo)航控制器子控制器的view的容器view)

  2. 導(dǎo)航條的內(nèi)容由棧頂控制器的navigationItem決定,因此導(dǎo)航控制器必須要有一個根控制器,因?yàn)樗旧聿痪邆渫暾娘@示功能,連自身的導(dǎo)航條也不能決定凰狞。

  3. 導(dǎo)航條上的子控件位置不由我們管理,只能管理尺寸

  4. UINavigationItem:是一個模型,決定導(dǎo)航條的內(nèi)容(左邊內(nèi)容,中間,右邊內(nèi)容)

  5. UIBarButtonItem:是一個UINavigationItem上按鈕的模型,決定導(dǎo)航條上按鈕的內(nèi)容

導(dǎo)航控制器-利用storyboard創(chuàng)建

1. 程序一啟動,就加載導(dǎo)航控制器,設(shè)置storyboard箭頭指向?qū)Ш娇刂破?2. 設(shè)置導(dǎo)航控制器的根控制器為UIViewController
3. 設(shè)置導(dǎo)航條的內(nèi)容,還有下一個控制器的返回按鈕
4. 利用storyboard做跳轉(zhuǎn),選中按鈕拖線
5. 利用按鈕,通過代碼實(shí)現(xiàn)回到上一個控制器,注意不能回拖,這樣不是指回到上一個控制器篇裁,而是跳轉(zhuǎn)到一個新的控制器。
6. 相比起storyboard創(chuàng)建UIViewController赡若,設(shè)置了窗口的根控制器為導(dǎo)航控制器后达布,還需要設(shè)置導(dǎo)航控制器的根控制器為UIViewController,并做好跳轉(zhuǎn)回返回設(shè)置

導(dǎo)航控制器的創(chuàng)建(代碼)

// 1.創(chuàng)建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

// 2.設(shè)置窗口的根控制器

// 創(chuàng)建導(dǎo)航控制器的根控制器
ViewController *vc = [[ViewController alloc] init];

// 導(dǎo)航控制器需要根控制器
// 導(dǎo)航控制器會把根控制器作為它的子控制器
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];

// initWithRootViewController:底層其實(shí)就是調(diào)用push方法,把根控制器作為導(dǎo)航控制器的子控制器壓入棧中
// 導(dǎo)航控制器會把子控制器的view添加到導(dǎo)航控制器專門存放子控制器的view上
// [nav pushViewController:vc animated:YES];

self.window.rootViewController = nav;

// 3.顯示窗口
[self.window makeKeyAndVisible];

導(dǎo)航控制器的子控制器

  1. 子控制器類型
    //獲取棧頂控制器
    nav.topViewController
    
    //模型控制器或棧頂控制器
    nav.visibleViewController
    
    //壓入棧的控制器(導(dǎo)航控制器的子控制器)
    @property(nonatomic,copy) NSArray *viewControllers;
    @property(nonatomic,readonly) NSArray *childViewControllers;//只讀
    
    //棧底控制器逾冬,pop不會被銷毀,只是移除父視圖
    nav.rootViewController
    
  • 子控制器管理原理
    導(dǎo)航控制器是通過棧管理子控制器,棧是先進(jìn)后出

  • 導(dǎo)航控制器的入棧操作
    1. 子控制器用到時跳轉(zhuǎn)黍聂,不是一開始全部入棧:
    1. 開發(fā)中是先給導(dǎo)航控制器添加根控制器,顯示根控制器的view,不需要顯示其他子控制器的view身腻。創(chuàng)建根控制器的方法(底層都是push方法壓入棧):
    1. 直接根據(jù)根控制器創(chuàng)建導(dǎo)航控制器
    2. 創(chuàng)建一個控制器产还,將控制器加入到導(dǎo)航控制器子控制器中,默認(rèn)第一個控制器是根控制器
    3. 創(chuàng)建一個控制器然后push到導(dǎo)航控制器的棧中

          2. 跳轉(zhuǎn)控制器的權(quán)利應(yīng)該交給用戶,由用戶決定進(jìn)入那個界面
    
      3. 用戶點(diǎn)擊根控制器的跳轉(zhuǎn)按鈕嘀趟,根控制器通過`push方法`將子控制器壓入棧脐区,并顯示控制器對應(yīng)的view
    
    //push方法能將某個控制器壓入棧
    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    
  1. 導(dǎo)航控制器的出棧操作
    1. 自動出棧點(diǎn)擊back返回,移除棧頂控制器,移除的控制器會被銷毀
    2. 主動出棧:通過pop手動出棧
    1. 主動出棧,要求出棧的控制器必須是棧里面的控制器,不能自己創(chuàng)建一個控制器出棧,會報出棧的控制器不存在的錯誤,可以用viewControllers或者childViewControllers拿到根控制器。
    2. pop控制器,不會馬上銷毀棧頂控制器,而是告訴導(dǎo)航控制器需要把棧頂控制器出棧,等到恰當(dāng)?shù)臅r間就會把棧頂控制器出棧,并且銷毀她按。

    //pop方法可以移除控制器
    //將棧頂?shù)目刂破饕瞥?- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
    
    //回到指定的子控制器
    - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
    
    //回到根控制器(棧底控制器)
    - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
    

UINavigationController對UIScrollView的邊距調(diào)整

  1. 默認(rèn)情況下, 如果一個控制器處在導(dǎo)航控制器管理中, 并且控制器的view是UIScrollView, 那么就會自動調(diào)整這個UIScrollView的contentInset
    1. UIEdgeInsetsMake(64, 0, 0, 0) // 導(dǎo)航條顯示
    2. UIEdgeInsetsMake(20, 0, 0, 0) // 導(dǎo)航欄隱藏
  • 在第1點(diǎn)的基礎(chǔ)上坡椒,若導(dǎo)航控制器又處在UITabBarController管理中, 那么就會自動調(diào)整這個UIScrollView的contentInset為
    1. UIEdgeInsetsMake(64, 0, 49, 0)
  • 如何禁止上述的影響?
    viewController.automaticallyAdjustsScrollViewInsets = NO;
    
  • 若該控制器的view不是UIScrollView或其子類,而是UIWebView尤溜,也會有這種自動調(diào)整效果倔叼,因?yàn)閁IWebView內(nèi)部有個scrollowView

  • 注意:如下兩種情況是沒有邊距調(diào)整效果的
    1. 導(dǎo)航控制器對子控制器的邊距調(diào)整,僅是對子控制器的View進(jìn)行調(diào)整宫莱;子控制器的View的子控件是UIScrollView及其子類則不受影響
    2. 如果控制器只是處在標(biāo)簽控制器(UITabBarController)管理中丈攒,而沒有被導(dǎo)航控制器管理,也不會有這種效果

  • 上述影響的作用:實(shí)現(xiàn)穿透導(dǎo)航欄和標(biāo)簽條效果
    1. IOS7之前授霸,tableView不是占據(jù)整個屏幕巡验,只是占據(jù)一部分,所以7之前沒有穿透效果碘耳。
    2. IOS7之后显设,tableView可以占據(jù)整個屏幕,上述默認(rèn)效果可以使得tableView穿透導(dǎo)航欄和標(biāo)簽條效果辛辨。

控制器的數(shù)據(jù)傳遞:順傳和逆?zhèn)?/h3>
1. 順傳
    1. 控制器的跳轉(zhuǎn)方向  : A -> C
    2. 數(shù)據(jù)的傳遞方向     : A -> C
    3. 數(shù)據(jù)的傳遞方式     :
        1. 在A的prepareForSegue:sender:方法中根據(jù)segue參數(shù)取得destinationViewController(控制器C)
        2. 直接給控制器C傳遞數(shù)據(jù)捕捂,然后在控制器C的viewDidLoad方法中取得數(shù)據(jù),來賦值給界面上的UI控件
2. 逆?zhèn)?    1. 控制器的跳轉(zhuǎn)方向  : A -> C
    2. 數(shù)據(jù)的傳遞方向    : C <- A
    3. 數(shù)據(jù)的傳遞方式    : 讓A成為C的代理, 在C中調(diào)用A的代理方法,通過代理方法的參數(shù)傳遞數(shù)據(jù)給A瑟枫;或者通過通知,也應(yīng)該可以用block回傳

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末指攒,一起剝皮案震驚了整個濱河市慷妙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌允悦,老刑警劉巖膝擂,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異隙弛,居然都是意外死亡架馋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門全闷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绩蜻,“玉大人,你說我怎么就攤上這事室埋。” “怎么了伊约?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵姚淆,是天一觀的道長。 經(jīng)常有香客問我屡律,道長腌逢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任超埋,我火速辦了婚禮搏讶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘霍殴。我一直安慰自己媒惕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布来庭。 她就那樣靜靜地躺著妒蔚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪月弛。 梳的紋絲不亂的頭發(fā)上肴盏,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機(jī)與錄音帽衙,去河邊找鬼菜皂。 笑死,一個胖子當(dāng)著我的面吹牛厉萝,可吹牛的內(nèi)容都是我干的恍飘。 我是一名探鬼主播榨崩,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼常侣!你這毒婦竟也來了蜡饵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤胳施,失蹤者是張志新(化名)和其女友劉穎溯祸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舞肆,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡焦辅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了椿胯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筷登。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哩盲,靈堂內(nèi)的尸體忽然破棺而出前方,到底是詐尸還是另有隱情,我是刑警寧澤廉油,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布惠险,位于F島的核電站,受9級特大地震影響抒线,放射性物質(zhì)發(fā)生泄漏班巩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一嘶炭、第九天 我趴在偏房一處隱蔽的房頂上張望抱慌。 院中可真熱鬧,春花似錦眨猎、人聲如沸抑进。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽单匣。三九已至,卻和暖如春宝穗,著一層夾襖步出監(jiān)牢的瞬間户秤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工逮矛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸡号,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓须鼎,卻偏偏與公主長得像鲸伴,于是被迫代替她去往敵國和親府蔗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

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