淺析iOS的頁面結(jié)構(gòu)

1、頁面結(jié)構(gòu)

相信很多人和我一樣,開發(fā)了很多iOS頁面但是確一直沒有去詳細剖析iOS頁面中的頁面結(jié)構(gòu)。先說下常規(guī)的APP開發(fā)套路,首先我們會使用UINaviagtionController來作為一個導航控制器來管理我們APP中的導航,然后我們會向?qū)Ш娇刂破髦衟ush或者pop UIViewController.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //1、創(chuàng)建窗口
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    //2、創(chuàng)建導航控制器,并設(shè)置導航控制器的根控制器
    OneViewController *rootVC = [[OneViewController alloc]init];
    UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:rootVC];
    //3、設(shè)置窗口的根控制器
    self.window.rootViewController = navigationController;
    //4、顯示窗口
    [self.window makeKeyAndVisible];
    return YES;
}

從代碼中我們可以發(fā)現(xiàn)我們的步驟是:
UIWindow--UINavigationController--UIViewController

通過上面的邏輯關(guān)系我們肯定會迷惑,不是應該一切能顯示的的東西都應該直接或者間接的繼承UIView嗎?這個就是蘋果處處強調(diào)的MVC設(shè)計理念了(View應該對應一個Controller來管理),其實我們在設(shè)置UINavigationController和UIViewController的時候系統(tǒng)自動會給我們添加繼承UIView的控件在UIWindows上面的。下面我們就來看看里面到底添加了哪些控件。

//遞歸顯示頁面的結(jié)構(gòu)
- (void)dumpView:(UIView *)aView atIndent:(int)indent into:(NSMutableString *)outstring
{
    for (int i = 0; i < indent; i++) [outstring appendString:@"--"];
    [outstring appendFormat:@"[%2d] %@\n", indent, [[aView class] description]];
    for (UIView *view in [aView subviews])
        [self dumpView:view atIndent:indent + 1 into:outstring];
}

- (NSString *) displayViews: (UIView *) aView

{
    NSMutableString *outstring = [[NSMutableString alloc] init];
    [self dumpView: [UIApplication sharedApplication].keyWindow  atIndent:0 into:outstring];
    return outstring;
}

輸出結(jié)果

頁面層次結(jié)構(gòu)

我們抽取主要的UIView轉(zhuǎn)換為樹這樣看的更清晰

頁面樹結(jié)構(gòu)

我們從圖中的層次結(jié)構(gòu)看出平時我們真正使用到的UIView和UINavigationBar不是直接添加到UIWindow里面的,而是有多個層次。并且還有些不是我們自己添加的UIView,這些是系統(tǒng)為了更好的實現(xiàn)功能而添加的,負責一些動畫布局處理。
UILayoutContainerView:這個是UINavigationController的容器View這個就想相當于UIViewController中的UIView;我們可以通過代碼,來看輸出類型。

NSLog(@"super-%@",[self.navigationController.view class]);

UINavigationTransitionView和UIViewControllerWrapperView是什么鬼
stackoverflow解釋
從里面的問答的基本意思是UINavigationTransitionView是UINaviagtionController來管理動畫的,UIViewControllerWrapperView是用來包含我們實際開發(fā)的UI的。從集成結(jié)構(gòu)我們也可以看出,UIView是包含在UIViewControllerWrapperView當中的。
通過下面的兩段代碼我們就可以得出我上圖中的劃線層次,

UINavigationController

    //輸出UINavigationController中的View
    NSLog(@"super-%@",[self.navigationController.view class]);
    for (UIView *view in self.navigationController.view.subviews) {
        NSLog(@"view-%@",[view class]);
    }

輸出結(jié)果

2016-11-04 19:56:59.420 UINavigationControllerDemo[57578:4726504] super-UILayoutContainerView
2016-11-04 19:56:59.421 UINavigationControllerDemo[57578:4726504] view-UINavigationTransitionView
2016-11-04 19:56:59.421 UINavigationControllerDemo[57578:4726504] view-UINavigationBar

UIViewController

//輸出UIViewController中的View
   NSLog(@"super-%@",[self.view class]);
   for (UIView *view in self.view.subviews) {
       NSLog(@"view-%@",[view class]);
   }

輸出結(jié)果

2016-11-04 20:01:56.655 UINavigationControllerDemo[57601:4729878] super-UIView
2016-11-04 20:01:56.655 UINavigationControllerDemo[57601:4729878] view-UIButton

2、UINavigationController、UINavigationBar和NavigationItem之間的關(guān)系

1、UINavigationBar是包含在UINavigationController中的;
2、NavigationItem是用于管理UINavigationBar中的子控件的對象。
注意:雖然UINavigationBar屬于UINavigationController,但是我們卻不能通過UINavigationController的NavigationItem屬性來控制導航欄中的子控件;這個是很迷惑的地方

  //通過控制器的navigationItem設(shè)置屬性
  self.navigationItem.title = @"首頁";
  //這樣設(shè)置無效
  self.navigationController.navigationItem.title = @"無效標題";

?導航欄的內(nèi)容由棧頂控制器的navigationItem屬性決定
?
?UINavigationItem有以下屬性影響著導航欄的內(nèi)容
?左上角的返回按鈕
@property(nonatomic,retain) UIBarButtonItembackBarButtonItem;
?中間的標題視圖
@property(nonatomic,retain) UIView titleView;
?中間的標題文字
@property(nonatomic,copy) NSString title;
?左上角的視圖
@property(nonatomic,retain) UIBarButtonItem
leftBarButtonItem;
?UIBarButtonItem
rightBarButtonItem 右上角的視圖
@property(nonatomic,retain) UIBarButtonItem
rightBarButtonItem; `

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 1,Search Bar 怎樣去掉背景的顏色(storyboard里只能設(shè)置background顏色,可是發(fā)現(xiàn)cl...
    以德扶人閱讀 2,431評論 2 50
  • 廢話不多說,直接上干貨 ---------------------------------------------...
    小小趙紙農(nóng)閱讀 3,421評論 0 15
  • 前言 由于最近兩個多月,筆者正和小伙伴們忙于對公司新項目的開發(fā),筆者主要負責項目整體架構(gòu)的搭建以及功能模塊的分工。...
    CoderMikeHe閱讀 27,107評論 74 270
  • 那天跟老爸騎摩托車一起回家,老媽在旁邊囑咐我“路很爛,把你爸爸抱著嘛。” 迷之不知手放哪兒。雙手抱著老爸的腰?自己...
    ido2閱讀 257評論 0 3
  • 沒有物質(zhì)的支持,又何來詩和遠方? 生長在貧困縣,看著浩南哥、頭文字D長大的我。(一不小心就暴露了年齡)總想出人頭地...
    da6a5b0809bf閱讀 317評論 0 0