Coding-iOS 的根視圖分析

前面分析了應用啓動時引導動畫的展示過程,動畫結束後根據會跳轉到登錄或者註冊界面(LoginViewController/RegisterViewController,另外我發現在連續登陸失敗3次之後會出現驗證碼的輸入框,關於登錄過程後續再進行分析),當用戶登錄完成之後會進入RootTabViewController視圖,該控制器裏面依次加載了五個RootViewController(項目、任務、冒泡、消息和Me,其中的Me指的是用戶)。RootTabViewController繼承自第三方庫RDVTabBarController,這個庫的用法類似於UITabBarController,可以通過底部的標籤項來切換上面說到的五個RootViewController。

目錄

按以下幾部分展開:


介紹RootTabViewController

首先看到重寫了- (id)initWithNibName: bundle: 方法(但是沒有添加內容,只是調用了父類的該方法)。然後可以看到- (void)viewDidLoad調用了- (void)setupViewControllers方法,這個是我們關注的重點。

setupViewControllers方法添加了5個五個RootViewController,並且定製了屏幕底部的標籤欄(設置標籤項在不同狀態下的圖標和背景圖片)。

- (void)setupViewControllers {

    // 加載Project_RootViewController
    Project_RootViewController *project = [[Project_RootViewController alloc] init];
    ... ...
    /* 以Project_RootViewController爲根視圖控制器, 初始化一個導航控制器 */
    UINavigationController *nav_project = [[BaseNavigationController alloc] initWithRootViewController:project];

    // 加載MyTask_RootViewController 和 Tweet_RootViewController
    MyTask_RootViewController *mytask = [[MyTask_RootViewController alloc] init];
    UINavigationController *nav_mytask = [[BaseNavigationController alloc] initWithRootViewController:mytask];

    RKSwipeBetweenViewControllers *nav_tweet = [RKSwipeBetweenViewControllers newSwipeBetweenViewControllers];
    [nav_tweet.viewControllerArray addObjectsFromArray:@[[Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeAll],
                                                         [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeFriend],
                                                         [Tweet_RootViewController newTweetVCWithType:Tweet_RootViewControllerTypeHot]]];
    nav_tweet.buttonText = @[@"冒泡廣場", @"朋友圈", @"熱門冒泡"];

    // 加載Message_RootViewController
    Message_RootViewController *message = [[Message_RootViewController alloc] init];
   ... ...
    UINavigationController *nav_message = [[BaseNavigationController alloc] initWithRootViewController:message];

    // 加載Message_RootViewController
    Me_RootViewController *me = [[Me_RootViewController alloc] init];
    me.isRoot = YES;
    UINavigationController *nav_me = [[BaseNavigationController alloc] initWithRootViewController:me];

    /* 將需要被管理的多個UIViewController組合成NSArray對象, 將這個NSArray對象設置成 RDVTabBarController的viewController屬性, 這樣就可以通過RDVTabBarController來切換顯示多個UIViewController */
    [self setViewControllers:@[nav_project, nav_mytask, nav_tweet, nav_message, nav_me]];

    [self customizeTabBarForController];
    self.delegate = self;
}

另外,可以注意到該方法(setupViewControllers)中用到了ReactiveCocoa 框架(基於響應式編程思想),關於這個框架的使用介紹,我找了幾篇寫的比較詳細的文章:《ReactiveCocoa入門教程》《ReactiveCocoa框架菜鳥入門》 ,可以參考一下。

/* RACObserve(TARGET, KEYPATH)  觀察TARGET的KEYPATH屬性,相當於KVO,產生一個RACSignal */
/* 使用combineLatest:reduce:方法 產生聚合信號(此處只有一個信號), 當該聚合信號產生一個新值時,reduce: block 會執行, block的返回值會賦值給project對象的badgeValue屬性 */
RAC(project, rdv_tabBarItem.badgeValue) = [RACSignal combineLatest:@[RACObserve([UnReadManager shareManager], project_update_count)]
                                                             reduce:^id(NSNumber *project_update_count){
                                                                 return project_update_count.integerValue > 0? kBadgeTipStr : @"";
                                                             }];

關於定製屏幕底部標籤欄的方法的使用可以參考RDVTabBarController庫的github說明,在本應用中的使用情況分析如下:

- (void)customizeTabBarForController {
    //定製標籤條(設置標籤項在不同狀態下的背景圖片和圖標)

    UIImage *backgroundImage = [UIImage imageNamed:@"tabbar_background"];
    NSArray *tabBarItemImages = @[@"project", @"task", @"tweet", @"privatemessage", @"me"];
    NSArray *tabBarItemTitles = @[@"項目", @"任務", @"冒泡", @"消息", @"我"];

    NSInteger index = 0;
    for (RDVTabBarItem *item in [[self tabBar] items]) {
        item.titlePositionAdjustment = UIOffsetMake(0, 3);
        /* 設置標籤項在選中和未選中狀態下分別對應的背景圖片 */
        [item setBackgroundSelectedImage:backgroundImage withUnselectedImage:backgroundImage];

        /* 設置標籤項在選中和未選中狀態下分別對應的圖標 */
        /* 以index=1爲例, 查找名爲 project_selected 的圖片(其中的 "%@" 表示NSArray返回指定index的對象) */
        /* 圖片 project_selected 位於 "image/tabbar/" 目錄下 */
        UIImage *selectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_selected",
                                                      [tabBarItemImages objectAtIndex:index]]];

        UIImage *unselectedimage = [UIImage imageNamed:[NSString stringWithFormat:@"%@_normal",
                                                        [tabBarItemImages objectAtIndex:index]]];
        [item setFinishedSelectedImage:selectedimage withFinishedUnselectedImage:unselectedimage];
        [item setTitle:[tabBarItemTitles objectAtIndex:index]];
        index++;
    }
}

RootTabViewController的根視圖爲Project_RootViewController,因此默認顯示的是項目視圖,可以通過底部的5個標籤欄來進行切換。
這裏寫圖片描述

對於頂部的搜索欄、”+”號按鈕,則是在Project_RootViewController中定義的,關於項目根視圖控制器的理解後面在進行分析。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章