一个iOS app几乎没有由一个控制器组成,除非这个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
     设置UIWindow的rootViewController为UINavigationController
     将第一个视图控制器设置为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的工作原理
     如果UITabBarController有N个子控制器,那么UITabBar内部就会有N个UITabBarButton作为子控件
     例如UITabBarController有3个子控制器,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. 设置UIWindow的rootViewController为UITabBarController
  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是来源控制器
                                     根据identifier去storyboard中找到对应的线,新建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;方法开始执行界面跳转操作
  • 如果segue的style是push
  • 取得sourceViewController所在的UINavigationController
  • 调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转
  • 如果segue的style是modal
  • 调用sourceViewController的presentViewController方法将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
  • 数据的传递方式: 在A的prepareForSegue:sender:方法中根据segue参数取得destinationViewController,也就是控制器B,直接给控制器B传递数据
  • 在B的viewDidLoad方法中取得数据,或者利用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

iOS -App主流框架UINavigationController && UITabBarController的简单使用的更多相关文章

  1. 搭建App主流框架_纯代码搭建(OC)

    转载自:http://my.oschina.net/hejunbinlan/blog/529778?fromerr=EmSuX7PR 搭建主流框架界面 源码地址在文章末尾 达成效果 效果图 注:本文部 ...

  2. 10分钟搭建 App 主流框架

    搭建主流框架界面 0.达成效果 我们玩iPhone应用的时候,有没发现大部分的应用都是上图差不多的结构,下面的TabBar控制器可以切换子控制器,上面又有Navigation导航条 我们本文主要是搭建 ...

  3. 十分钟搭建App主流框架

    搭建主流框架界面 0.达成效果 Snip20150904_5.png 我们玩iPhone应用的时候,有没发现大部分的应用都是上图差不多的结构,下面的TabBar控制器可以切换子控制器,上面又有Navi ...

  4. iOS边练边学--UITabBarController的简单使用

    一.UITabBarController的使用步骤 初始化UITabBarController 设置UIWindow的rootViewController为UITabBarController 根据具 ...

  5. iOS开发UI篇—APP主流UI框架结构

    iOS开发UI篇—APP主流UI框架结构 一.简单示例 说明:使用APP主流UI框架结构完成简单的界面搭建 搭建页面效果:                                二.搭建过程和 ...

  6. iOS开发——UI进阶篇(十三)UITabBarController简单使用,qq主流框架

    一.UITabBarController简单使用 // 程序加载完毕 - (BOOL)application:(UIApplication *)application didFinishLaunchi ...

  7. iOS开发——控制器OC篇&UINavigationController&UITabBarController详解

    UINavigationController&UITabBarController详解 一:UINavigationController 控制器的属性: UINavigationControl ...

  8. iOS开发之旅:实现一个APP界面框架

    在上一篇博客中,给大家介绍了一下我们传统的 APP 界面框架-标签导航的一些优缺点,在这篇文章中我会来给大家演示,如何用代码去实现这一框架.本次的实现我会分成俩部分来讲,好了闲话少说,接下来进入到开发 ...

  9. MUI框架-05-用MUI做一个简单App

    MUI框架-05-用MUI做一个简单App MUI 是一个前端框架,前端框架就像 Bootstrap,EasyUI,Vue ,为了做 app 呢,就有了更加高效的 MUI,我觉得前端框架有很多,也没有 ...

随机推荐

  1. 24个经典的MySQL索引问题,你都遇到过哪些?

    索引 1.什么是索引? 2.索引有哪些优缺点? 3.索引使用场景(重点) 4.索引有哪几种类型? 5.索引的数据结构(b树,hash) 6.索引的基本原理 7.索引算法有哪些? 8.索引设计的原则? ...

  2. python re 里面match 和search的区别

    re.match()从开头开始匹配string. re.search()从anywhere 来匹配string. 例子: >>> re.match("c", &q ...

  3. SSD1306(OLED驱动芯片)指令详解

    基础命令: 1.页地址模式下设置列起始地址低位(Set Lower Column Start Address For Page Addressing Mode)(00h~0Fh) 此指令用于在页地址模 ...

  4. [!] Unable to find a pod with name, author, summary, or description matching `AFNetworking`

    大量的答案是删除~/Library/Caches/CocoaPods/search_index.json  没有起作用 有用答案: https://blog.csdn.net/qq_35827461/ ...

  5. CF894B Ralph And His Magic Field

    题目链接:http://codeforces.com/contest/894/problem/B 题目大意: 往一个 \(n \times m\) 的网格中填数字 \((1 \le n,m \le 1 ...

  6. SecureCRT 简单运用

    1.想要从本地电脑将文件通过secureCRT传输到远程服务器如下目录 2.在SecureCRT界面中使用快捷键[Alt+P] 打开了SFTP的界面 3.找到你要传的文件的地址[E:\a.zip] 4 ...

  7. 【NLP】常用优化方法

    目录 梯度下降法 动量法 AdaGrad算法 RMSProP算法 AdaDelta算法 Adam算法 1.梯度下降法 梯度下降法可以分为三种,批量梯度下降法(BGD).小批量梯度下降(MBGD).随机 ...

  8. iOS开发MD5、SHA1

    MD5: + (NSString *)md5:(NSString *)input { const char *cStr = [input UTF8String]; unsigned char dige ...

  9. 在win10上搭建pyspark,

    最近在研究Spark,准确的说是pyspark,为了搭个测试环境,之前一直在云上开Linux机器来搭Hadoop,但是Spark可以Local执行,我就打算在本地搭个环境.遇到了一些问题,记录一下,也 ...

  10. Python 每日一练 | Flask 实现半成品留言板

    留言板Flask实现 引言 看了几天网上的代码,终于写出来一个半成品的Flask的留言板项目,为什么说是半成品呢?因为没能实现留言板那种及时评论刷新的效果,可能还是在重定向上有问题 或者渲染写的存在问 ...