1. 程式人生 > >iOS -App主流框架UINavigationController && UITabBarController的簡單使用

iOS -App主流框架UINavigationController && UITabBarController的簡單使用

 一個iOSapp幾乎沒有由一個控制器組成,除非這個app非常簡單。       當app中有多個控制器的時候,就需要對這些控制器進行管理,1個控制器去管理其他多個控制器;       如圖所示:        
  • 蘋果公司為我提供了兩個特殊的控制器,UINavigationController和UITabBarController去管理其它控制器;
    一. UIViewController的簡單使用           利用UINavigationController,可以輕鬆地管理多個控制器,輕鬆完成控制器之間的切換,典型例子就是系統自帶的“設定”應用;
            
 (1)UINavigationController的view結構
            
(2)UINavigationController工作原理                  UINavigationController以棧的形式儲存子控制器      如圖:       
  • 使用push方法能將某個控制器壓入棧
     - (void)pushViewController:(UIViewController*)viewController animated:(BOOL)animated;
  • 使用pop方法可以移除棧頂控制器
          三種移除方式:
                將棧頂的控制器移除      - (UIViewController*)popViewControllerAnimated:(BOOL)animated;                 回到指定的子控制器      - (NSArray*)popToViewController:(UIViewController*)viewController animated:(BOOL)animated;                 回到根控制器(棧底控制器)      - (NSArray*)popToRootViewControllerAnimated:(
BOOL)animated; 導航欄的內容
  • 導航欄的內容由棧頂控制器的navigationItem屬性決定
  • UINavigationItem有以下屬性影響著導航欄的內容
          左上角的返回按鈕      @property(nonatomic,retain)UIBarButtonItem*backBarButtonItem;           中間的標題檢視      @property(nonatomic,retain)UIView          *titleView;           中間的標題文字      @property(nonatomic,copy)  NSString        *title;           左上角的按鈕      @property(nonatomic,retain)UIBarButtonItem*leftBarButtonItem;           右上角的按鈕      @property(nonatomic,retain)UIBarButtonItem*rightBarButtonItem; UINavigationController的使用步驟      初始化UINavigationController      設定UIWindowrootViewControllerUINavigationController      將第一個檢視控制器設定為UINavigationController的根檢視控制器           通過push方法新建子控制器      通過pop方法返回到上一級控制器
eg:
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //例項化window
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    //建立UINavigationController
    UINavigationController *nvc = [[UINavigationController alloc] init];

    //建立兩個UIViewController,並設定背景色,push cv1,兩秒後push vc2
    UIViewController *cv1 = [[UIViewController alloc] init];
    cv1.view.backgroundColor = [UIColor redColor];

    UIViewController *cv2 = [[UIViewController alloc] init];
    cv2.view.backgroundColor = [UIColor greenColor];
    [nvc pushViewController:cv1 animated:YES];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [nvc pushViewController:cv2 animated:YES];
    });

    //將UINavigationController設為window的根控制器
    self.window.rootViewController = nvc;
    [self.window makeKeyAndVisible];
    return YES;
}

//UINavigationController的另一種初始化方法 - (instancetype)initWithRootViewController:(UIViewController*)rootViewController;// 
二.UITabBarController的簡單使用      跟UINavigationController類似,UITabBarController也可以輕鬆地管理多個控制器,輕鬆完成控制器之間的切換,典型例子就是QQ、微信等應用。       
1.UITabBarController的view結構
      2.UITabBarController的工作原理 如果UITabBarControllerN個子控制器,那麼UITabBar內部就會有NUITabBarButton作為子控制元件      例如UITabBarController3個子控制器,UITabBar的結構大致如下:
      
   UITabBarButton裡面顯示什麼內容,由對應子控制器的tabBarItem屬性決定    UITabBarItem有以下屬性影響著UITabBarButton的內容         
     標題文字     @property(nonatomic,copy)NSString*title;      圖示     @property(nonatomic,retain)UIImage*image;      選中時的圖示     @property(nonatomic,retain)UIImage*selectedImage;      提醒數字     @property(nonatomic,copy)NSString*badgeValue
 新增單個子控制器      - (void)addChildViewController:(UIViewController*)childController; UITabBarController的使用步驟
  1. 初始化UITabBarController
  2. 設定UIWindowrootViewControllerUITabBarController
  3. 根據具體情況,通過addChildViewController方法新增對應個數的子控制器
     eg:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    UITabBarController *tabVc = [[UITabBarController alloc] init];

    UIViewController *vcOne = [[UIViewController alloc] init];
    vcOne.view.backgroundColor = [UIColor redColor];
    vcOne.tabBarItem.title = @"one";
    vcOne.tabBarItem.image = [UIImage imageNamed:@"icon1"];
    [tabVc addChildViewController:vcOne];

    UIViewController *vcTwo = [[UIViewController alloc] init];
    vcTwo.view.backgroundColor = [UIColor blueColor];
    vcTwo.tabBarItem.title = @"two";
    vcTwo.tabBarItem.image = [UIImage imageNamed:@"icon2"];
    [tabVc addChildViewController:vcTwo];

    self.window.rootViewController = tabVc;
    [self.window makeKeyAndVisible];
    return YES;
}


執行效果:
      三.目前主流的App框架           如:qq,微信,UITabBarController中巢狀UINavigationController                          如:易信等 UINavigationController中巢狀UITabBarController               以上,並非嚴格意義上上的巢狀,TabBarController和NavigationController組合使用,能達到非常不錯的效果。 四.Segue      以上TabBarController和NavigationController的簡單使用,都是幹掉main.storyboard後用程式碼的方式來建立; 當使用main.storyboard時,就會涉及到segue。      什麼是segue呢?       Storyboard上每一根用來介面跳轉的線,都是一個UIStoryboardSegue物件(簡稱Segue           如圖所示:            
1.Segue的屬性           唯一標識      @property(nonatomic,readonly)NSString*identifier;           來源控制      @property(nonatomic,readonly)idsourceViewController;           目標控制器      @property(nonatomic,readonly)iddestinationViewController;             如圖所示:                        2.Segue的型別      根據Segue的執行(跳轉)時刻,Segue可以分為2大型別
  1. 自動型:點選某個控制元件後(比如按鈕),自動執行Segue,自動完成介面跳轉
  2. 手動型:需要通過寫程式碼手動執行Segue,才能完成介面跳轉
          拖線方式:           按住Control鍵,直接從控制元件拖線到目標控制器,此時為“自動型Segue”
  • 按住Control鍵,從來源控制器拖線到目標控制器此時為“手動型Segue”,此時為了方便使用,需要設定Segue的identifier屬性。
  • 使用“手動型Segue”時:在需要的時刻,由來源控制器執行perform方法呼叫對應的Segue
  • [self performSegueWithIdentifier:identifiersender:nil];
               完整過程是:self是來源控制器                                      根據identifierstoryboard中找到對應的線,新建UIStoryboardSegue物件                                      設定Segue物件的sourceViewController(來源控制器)                                                新建並且設定Segue物件的destinationViewController(目標控制器)           我們可以根據需如果點選某個控制元件,不需要做任何判斷,直接跳轉到下一個介面,則使用“自動型Segue”,反之則用用“手動型Segue”;   3.常用的方法 performSegueWithIdentifier:sender      呼叫sourceViewController的下面方法,做跳轉前的準備工作並傳入建立好的Segue物件   - (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender; sender呼叫performSegueWithIdentifier:sender:方法時傳入的物件
  • 呼叫Segue物件的- (void)perform;方法開始執行介面跳轉操作
  • 如果seguestylepush
  • 取得sourceViewController所在的UINavigationController
  • 呼叫UINavigationControllerpush方法將destinationViewController壓入棧中,完成跳轉
  • 如果seguestylemodal
  • 呼叫sourceViewControllerpresentViewController方法將destinationViewController展示出來
4.Modal
  • 除了push之外,還有另外一種控制器的切換方式,那就是Modal
  • 任何控制器都能通過Modal的形式展示出來
  • Modal的預設效果:新控制器從螢幕的最底部往上鑽,直到蓋住之前的控制器為止
  • Modal的形式展示控制器

- (void)presentViewController:(UIViewController*)viewControllerToPresent animated: (BOOL)flag completion:(void(^)(void))completion

  • 關閉當初Modal出來的控制器

- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void(^)(void))completion;

  • 原則:誰Modal,誰dismiss
5.控制器的資料傳遞 控制器的資料傳遞(順傳)
  • 控制器的跳轉方向:  A->B
  • 資料的傳遞方向:      A -> B
  • 資料的傳遞方式AprepareForSegue:sender:方法中根據segue引數取得destinationViewController,也就是控制器B直接給控制器B傳遞資料
  • BviewDidLoad方法中取得資料或者利用setter方法設定介面上的UI控制元件;
          eg: 將當前的控制器中的self.modelArray[indexPath.row]資料傳遞給EditViewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        EditViewController *editVc = (EditViewController *)segue.destinationViewController;
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        editVc.model = self.modelArray[indexPath.row];
     }

    需要重寫EditViewController 的屬性model的setter;然後在viewDidLoad的設定EditViewController內部其它屬性賦值。(需要謹防viewDidLoad還沒有載入完成,就對內部的控制元件賦值,否則會bug); @property (nonatomic,strong)Model *model;          控制器的資料傳遞(逆傳
  • 控制器的跳轉方向  A-> B
  • 資料的傳遞方向:      B -> A
  • 資料的傳遞方式:A成為B的代理,在B中呼叫A的代理方法,通過代理方法的引數傳遞資料給A