zoukankan      html  css  js  c++  java
  • ioS UI-导航控制器(NavigationController)

      1 #import "AppDelegate.h"
      2 #import "ViewController.h"
      3 
      4 @interface AppDelegate ()
      5 
      6 @end
      7 
      8 @implementation AppDelegate
      9 
     10 
     11 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     12     //1.窗口初始化
     13     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
     14     
     15     //2.视图控制器
     16     ViewController *vc = [[ViewController alloc] init];
     17     //VC.view.backgroundColor = [UIColor cyanColor];
     18     //[self.window makeKeyAndVisible];
     19 
     20     
     21     //3.创建一个导航控制器对象,并将rootVC作为导航控制器的根视图控制器
     22     UINavigationController *navCtr = [[UINavigationController alloc] initWithRootViewController:vc];
     23     //简易更改外观
     24     [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navBg.png"] forBarMetrics:UIBarMetricsDefault];
     25     
     26     //4.将导航控制器设置为根视图控制器
     27     self.window.rootViewController =navCtr;
     28     //5.关键步骤:让当前窗口作为keyWindow(唯一性)主窗口并且可见
     29     [self.window makeKeyAndVisible];
     30     
     31     return YES;
     32 }
     33 
     34 
     35 #import "ViewController.h"
     36 #import "FirstViewController.h"
     37 @interface ViewController ()
     38 
     39 @end
     40 
     41 @implementation ViewController
     42 
     43 /*
     44  导航控制器->视图控制器->视图
     45  当根控制器设置为导航控制器时
     46  
     47  UINavigationController
     48  是用于构建分层应用程序的主要工具,主要采用栈形式来实现视图。任何类型的视图控制器都可放入栈中。在设计导航控制器时需要指定根视图即用户看到的第一个视图。根视图控制器是被导航控制器推入到栈中的第一个视图控制器。当用户查看下一个试图时,栈中将加入一个新的视图控制器,它所控制的视图将展示给用户。我们可以通过导航按钮来操作分层的应用程序,用它来控制视图的推入或推出
     49  */
     50 
     51 - (void)viewDidLoad {
     52     [super viewDidLoad];
     53     self.title = @"ViewController";
     54     self.view.backgroundColor = [UIColor purpleColor];
     55     
     56     
     57     UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(myAdd)];
     58     self.navigationItem.rightBarButtonItem = rightBtn;
     59 
     60     
     61     UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
     62     btn.frame = CGRectMake(90, 90, 200, 50);
     63     [btn setTitle:@"Go to the next" forState:UIControlStateNormal];
     64     [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
     65     btn.backgroundColor = [UIColor whiteColor];
     66     [self.view addSubview:btn];
     67     
     68     [btn addTarget:self action:@selector(btnPushClick) forControlEvents:UIControlEventTouchUpInside];
     69     
     70 
     71 }
     72 
     73 #pragma mark - 自定义方法
     74 
     75 #pragma mark -UIBarButtonItem的右耳目关联方法
     76 - (void)myAdd
     77 {
     78     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Touch" message:@"添加某种功能" delegate:self cancelButtonTitle:@"Good Job" otherButtonTitles: nil];
     79     [alert show];
     80 }
     81 
     82 #pragma mark - 按钮关联方法-压栈
     83 - (void)btnPushClick
     84 {
     85     //看到的是栈顶视图,想看下一个必需把它压进来
     86     FirstViewController *firstVC = [[FirstViewController alloc] init];
     87     [self.navigationController pushViewController:firstVC animated:YES];
     88 }
     89 
     90 - (void)didReceiveMemoryWarning {
     91     [super didReceiveMemoryWarning];
     92     // Dispose of any resources that can be recreated.
     93 }
     94 
     95 @end
     96 
     97 
     98 
     99 #import "FirstViewController.h"
    101 
    102 @interface FirstViewController ()
    103 
    104 @end
    105 
    106 @implementation FirstViewController
    107 
    108 - (void)viewDidLoad {
    109     [super viewDidLoad];
    110     self.title = @"FirstViewController";
    111     self.view.backgroundColor = [UIColor lightGrayColor];
    112     
    113     UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
    114     btn.frame = CGRectMake(90, 90, 200, 50);
    115     [btn setTitle:@"Go to the next" forState:UIControlStateNormal];
    116     [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    117     btn.backgroundColor = [UIColor whiteColor];
    118     [self.view addSubview:btn];
    119     
    120     [btn addTarget:self action:@selector(btnPushClick) forControlEvents:UIControlEventTouchUpInside];
    121     
    122     
    123 }
    124 #pragma mark - 自定义方法
    125 #pragma mark - 按钮关联方法
    126 - (void)btnPushClick
    127 {
    128     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Congrautulations" message:@"当前为最后一页" delegate:self cancelButtonTitle:@"取消" otherButtonTitles: nil];
    129     [alert show];
    130 
    131 }
    132 
    133 
    134 - (void)didReceiveMemoryWarning {
    135     [super didReceiveMemoryWarning];
    136     // Dispose of any resources that can be recreated.
    137 }
    138 
    139 
    140 @end

    一、导航控制器的一些属性和基本使用

    1.把子控制器添加到导航控制器中的四种方法

    (1)

     1.创建一个导航控制器

        UINavigationController *nav=[[UINavigationControlleralloc]init];

    2.设置导航控制器为window的根视图

        self.window.rootViewController=nav;

    3.添加

        YYOneViewController  *one = [[YYOneViewController  alloc] init];

        [nav pushViewController:one animated:YES];

    (2)

     1.创建一个导航控制器

           UINavigationController *nav=[[UINavigationControlleralloc]init];

     2.设置导航控制器为window的根视图

     self.window.rootViewController=nav;

     3.添加

    YYOneViewController  *one = [[YYOneViewController  alloc] init];

     [nav addChildViewController:one];

    (3)

     1.创建一个导航控制器

           UINavigationController *nav=[[UINavigationControlleralloc]init];

     2.设置导航控制器为window的根视图

     self.window.rootViewController=nav;

    3.添加

    YYOneViewController  *one = [[YYOneViewController  alloc] init];

    nav.viewControllers=@[one];(添加到导航控制器的栈中)

    说明:nav.viewControllers;== nav.childViewControllers;注意该属性是只读的,因此不能像下面这样写。nav.childViewControllers = @[one];

    (4)最常用的方法

     YYOneViewController *one=[[YYOneViewController alloc]init];

     UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:one];

    2.当前子控制器界面导航栏的标题以及对应返回标题的设置

        self.navigationItem.title=@"第一个界面";

        self.navigationItem.backBarButtonItem=[[UIBarButtonItemalloc]initWithTitle:@"返回一"style:UIBarButtonItemStylePlain target:nilaction:nil];

    3.给导航栏添加按钮

    说明:可添加一个,也可以添加多个(数组)

       添加导航栏左边的按钮(添加一个相机图标的按钮),会盖掉返回

        self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:nil action:nil];

    4.界面跳转

    跳转到第二个界面(当前为第三个,移除当前栈顶的控制器) [self.navigationControllerpopViewControllerAnimated:YES];

       移除处理栈底控制器之外的所有控制器  [self.navigationControllerpopToRootViewControllerAnimated:YES];

      只要传入栈中的某一个控制器,就会跳转到指定控制器 [self.navigationController popToViewController:<#(UIViewController *)#> animated:<#(BOOL)#>];

    5.UINavigationController的子控制器

    UINavigationController以栈的形式保存子控制器

    @property(nonatomic,copy) NSArray *viewControllers;

    @property(nonatomic,readonly) NSArray *childViewControllers;

    使用push方法能将某个控制器压入栈

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;

    使用pop方法可以移除控制器
    Ø将栈顶的控制器移除

    - (UIViewController *)popViewControllerAnimated:(BOOL)animated;

    回到指定的子控制器

    - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;

    回到根控制器(栈底控制器)

    - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;

    6.如何修改导航栏的内容

    导航栏的内容由栈顶控制器的navigationItem属性决定
     
    UINavigationItem有以下属性影响着导航栏的内容
    左上角的返回按钮

    @property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;

    中间的标题视图

    @property(nonatomic,retain) UIView          *titleView;

    中间的标题文字

    @property(nonatomic,copy)   NSString        *title;

    左上角的视图

    @property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;

    UIBarButtonItem *rightBarButtonItem  右上角的视图

    @property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;

    二、导航控制器通过栈来管理子控制器

    示意图

    说明:

    导航控制器是通过栈的形式来管理子控制器的(先进后出)

    显示在导航控制器上得view永远是栈顶控制器的view

    一个导航控制器只有一个导航条,也就是说所有的自控制器公用一个导航条。

    三、使用storyboard创建导航控制器以及控制器的生命周期

    1.基本过程

    新建一个项目,系统默认的主控制器继承自UIViewController,把主控制器两个文件删掉。

    在storyboard中,默认的控制器是View Controller,而我们需要的是导航控制器,那么就把系统的给删掉,拖一个导航控制器进来,导航控制器中默认的第一个子控制器是一个tableview controller,这里不需要,把它删掉,重新拖三个View Controller到界面上进行连线,简单的设置就可以了。

              

    按钮连线,按住ctrl,右边界面选择push。

      

    完成基本设置后的界面如下:

    经过这么几步简单的设置,就可以实现一个简单的多页面切换。为开发提供了极大的方便,但storyboard也不是万能的,要注意在开发中,如果在最后一个页面添加一个按钮,让它直接跳转到上一个页面会出现问题。

    提示:storyboard能做的事情,使用代码都能做,但是代码能够做的事情,storyboard不一定能够做。

    通过拖拉控件即可完成简单的界面设置。

    下面这样的连线会出现问题:(从后面的控制器跳转到前面,只能通过代码来实现)

    产生问题的原因:(当点击返回的时候,不是先把第三个控制器移除栈顶,而是先创建TWO控制器,此时栈里有四个控制器,栈顶的为TWO).

    2.什么是Segue

    Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue)

    3.Segue的属性
    每一个Segue对象,都有3个属性
    唯一标识

    @property (nonatomic, readonly) NSString *identifier;

    来源控制器

    @property (nonatomic, readonly) id sourceViewController;

    目标控制器

    @property (nonatomic, readonly) id destinationViewController;

    4.Segue的类型

    根据Segue的执行(跳转)时刻,Segue可以分为2大类型
    自动型:点击某个控件后(比如按钮),自动执行Segue,自动完成界面跳转 
    手动型:需要通过写代码手动执行Segue,才能完成界面跳转
     
    5.自动型Segue
     
    按住Control键,直接从控件拖线到目标控制器
    点击“登录”按钮后,就会自动跳转到右边的控制器
    如果点击某个控件后,不需要做任何判断,一定要跳转到下一个界面,建议使用“自动型Segue”
     
    6.手动型Segue
     
    按住Control键,从来源控制器拖线到目标控制器
    手动型的Segue需要设置一个标识(如右图)
    在恰当的时刻,使用perform方法执行对应的Segue

    [self performSegueWithIdentifier:@"login2contacts" sender:nil];

    // Segue必须由来源控制器来执行,也就是说,这个perform方法必须由来源控制器来调用

    如果点击某个控件后,需要做一些判断,也就是说:满足一定条件后才跳转到下一个界面,建议使用“手动型Segue”
     
    7.performSegueWithIdentifier:sender:
     
    利用performSegueWithIdentifier:方法可以执行某个Segue,完成界面跳转
     
    接下来研究performSegueWithIdentifier:sender:方法的完整执行过程

    [self performSegueWithIdentifier:@“login2contacts” sender:nil];

    // 这个self是来源控制器

    1>根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象
    设置Segue对象的sourceViewController(来源控制器)
    新建并且设置Segue对象的destinationViewController(目标控制器)
    2>调用sourceViewController的下面方法,做一些跳转前的准备工作并且传入创建好的Segue对象

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

    // 这个sender是当初performSegueWithIdentifier:sender:中传入的sender

    3>调用Segue对象的- (void)perform;方法开始执行界面跳转操作
    取得sourceViewController所在的UINavigationController
    调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转

    8.Sender参数的传递

    [self performSegueWithIdentifier:@“login2contacts” sender:@“jack”];

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;

    注意:

    1.导航栏遮住UIView问题

    IOS7的视图有个边缘延伸的属性:edgesForExtendedLayout, 
    其默认值是UIExtendedEdgeAll。 
    只要将其改成UIExtendedEdgeNone即可,要注意的是在IOS7以下版本会出现bug。 
    所以在UIViewController 的viewDidLoad里加上下面代码就完美解决了这个问题 
     
    if( ([[[UIDevicecurrentDevice] systemVersion] doubleValue]>=7.0)) {
            self.edgesForExtendedLayout = UIRectEdgeNone;
            self.extendedLayoutIncludesOpaqueBars = NO;
            self.modalPresentationCapturesStatusBarAppearance = NO;
    }
     
    2.导航栏的内容由导航控制器的栈顶元素决定
     
     
  • 相关阅读:
    DATA_PUMP_DIR impdp 指定导出目录
    MasScan
    VMWare:vSphere6 企业版参考序列号
    ORA-12519: TNS:no appropriate service handler found 解决
    百度IOT
    IPMI远程管理一点记录
    关于parallel(并行)的几个基本常识
    hdu 4811 数学 不难
    关于i++ 和 ++i
    sqlplus中怎么将你全部的操作和结果记录保存到你指定的文件里
  • 原文地址:https://www.cnblogs.com/oc-bowen/p/5089895.html
Copyright © 2011-2022 走看看