#import "AppDelegate.h"
#import "ViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//1.窗口初始化
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; //2.视图控制器
ViewController *vc = [[ViewController alloc] init];
//VC.view.backgroundColor = [UIColor cyanColor];
//[self.window makeKeyAndVisible]; //3.创建一个导航控制器对象,并将rootVC作为导航控制器的根视图控制器
UINavigationController *navCtr = [[UINavigationController alloc] initWithRootViewController:vc];
//简易更改外观
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navBg.png"] forBarMetrics:UIBarMetricsDefault]; //4.将导航控制器设置为根视图控制器
self.window.rootViewController =navCtr;
//5.关键步骤:让当前窗口作为keyWindow(唯一性)主窗口并且可见
[self.window makeKeyAndVisible]; return YES;
} #import "ViewController.h"
#import "FirstViewController.h"
@interface ViewController () @end @implementation ViewController /*
导航控制器->视图控制器->视图
当根控制器设置为导航控制器时 UINavigationController
是用于构建分层应用程序的主要工具,主要采用栈形式来实现视图。任何类型的视图控制器都可放入栈中。在设计导航控制器时需要指定根视图即用户看到的第一个视图。根视图控制器是被导航控制器推入到栈中的第一个视图控制器。当用户查看下一个试图时,栈中将加入一个新的视图控制器,它所控制的视图将展示给用户。我们可以通过导航按钮来操作分层的应用程序,用它来控制视图的推入或推出
*/ - (void)viewDidLoad {
[super viewDidLoad];
self.title = @"ViewController";
self.view.backgroundColor = [UIColor purpleColor]; UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(myAdd)];
self.navigationItem.rightBarButtonItem = rightBtn; UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
btn.frame = CGRectMake(, , , );
[btn setTitle:@"Go to the next" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor whiteColor];
[self.view addSubview:btn]; [btn addTarget:self action:@selector(btnPushClick) forControlEvents:UIControlEventTouchUpInside]; } #pragma mark - 自定义方法 #pragma mark -UIBarButtonItem的右耳目关联方法
- (void)myAdd
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Touch" message:@"添加某种功能" delegate:self cancelButtonTitle:@"Good Job" otherButtonTitles: nil];
[alert show];
} #pragma mark - 按钮关联方法-压栈
- (void)btnPushClick
{
//看到的是栈顶视图,想看下一个必需把它压进来
FirstViewController *firstVC = [[FirstViewController alloc] init];
[self.navigationController pushViewController:firstVC animated:YES];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end #import "FirstViewController.h" @interface FirstViewController () @end @implementation FirstViewController - (void)viewDidLoad {
[super viewDidLoad];
self.title = @"FirstViewController";
self.view.backgroundColor = [UIColor lightGrayColor]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
btn.frame = CGRectMake(, , , );
[btn setTitle:@"Go to the next" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor whiteColor];
[self.view addSubview:btn]; [btn addTarget:self action:@selector(btnPushClick) forControlEvents:UIControlEventTouchUpInside]; }
#pragma mark - 自定义方法
#pragma mark - 按钮关联方法
- (void)btnPushClick
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Congrautulations" message:@"当前为最后一页" delegate:self cancelButtonTitle:@"取消" otherButtonTitles: nil];
[alert show]; } - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @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.导航栏的内容由导航控制器的栈顶元素决定
 
 

ioS UI-导航控制器(NavigationController)的更多相关文章

  1. 猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController

    猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243?viewmode=contents 一:加入导航控制器 上一篇博 ...

  2. AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController

    AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...

  3. AJ学IOS 之微博项目实战(6)导航控制器NavigationController 的滑动回退功能实现

    AJ分享,必须精品 一:效果 第二篇里面写了怎样自定义navigation实现自定义的导航控制器左右按钮样式,但是当我们自己实现后,系统自带的向右边滑动来实现回退的功能就不能用了. 这里主要实现滑动回 ...

  4. iOS:导航控制器侧滑出栈实现

    介绍:在iOS中,导航控制器UINavigationController是默认实现左侧边缘侧滑手势出栈的,但是如果当开发者对导航控制器子控制实现自定义leftBaButtonItem时,这个侧滑功能就 ...

  5. IOS UINavigationController 导航控制器

    /** 导航控制器掌握: 1.创建导航控制器 UINavigationController *nav = [[UINavigationController alloc] initWithRootVie ...

  6. 多界面开发 、 导航控制器(NavigationController)

    1 VC之间的跳转和正向传值 1.1 问题 在实际的开发中更多的应用都会有多个页面组成,每个页面展示不同的信息,页面之间的跳转是由视图控制器来实现的,本案例实现两个页面的之间的跳转和页面之间的正向传值 ...

  7. IOS中导航控制器的代理及隐藏控制器刚出现时的滚动条

    一.导航控制器的代理 1.UINavigationController的delegate属性 2.代理方法 1> 即将显示新控制器时调用 /* navigationController : 导航 ...

  8. IOS之导航控制器

    UINavigationController是用于构建分层应用程序的主要工具,主要采用栈形式来实现视图.任何类型的视图控制器都可放入栈中.在设计导航控制器时需要指定根视图即用户看到的第一个视图.根视图 ...

  9. iOS结合导航控制器和标签栏控制器

    <span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name=& ...

  10. iOS 隔离导航控制器

    题外话:最近这两个月一直很闲,项目上基本没有啥大的需求.对于程序员来说,如果没有需求其实是一件很难受的事情,之前好多次在项目中没事找事,该优化的优化,该整理的整理.可能好多程序员都遇到过与我类似的情况 ...

随机推荐

  1. linux查看内存free

    free 加参数-b/k//m/g,以b.k.m.g的大小显示结果,默认以k显示 [root@oldboy ~]# free total used free shared buffers cached ...

  2. 在ubuntu英文系统下使用中文输入法

    How to install and use Chinese Input Method in the English Locale in Ubuntu ?(1) Check if there exis ...

  3. php在Nginx环境下进行刷新缓存立即输出,实现常驻进程轮询。

    以下面这段代码并不会逐个输出,而是当浏览器筹够一定字节数进行统一输出,结果显而易见,10秒后一次性输出所有内容 for($i=0;$i<10;$i++){ echo $i.'</br> ...

  4. [noip模拟题]排队

    [问题描述] 小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性.他们希望恰好有k对同学是高的在前,矮的在后,其余都是矮的在前,高的在后.如当n=5,k= ...

  5. deepin linux java开发环境搭建全系列

    一.jdk安装 下载并解压到Java文件,这个文件是我自己放的位置 配置环境变量 第一次使用终端需要设置管理员密码 之后开始设置环境变量 sudo vim /etc/profile :wq 保存并退出 ...

  6. jQuery 源码分析:当 selector 传来一个函数时,怎么进行处理?

    本文章为 0.9 版本,将会在稍后润色更新.本文使用的 jQuery 版本为 3.4.0 我们知道使用 $ 操作符时,可以往里面塞很多类型的参数,字符串,对象,函数...,jQuery 会根据不同的参 ...

  7. Go第八篇之包的使用

    Go 语言的源码复用建立在包(package)基础之上.Go 语言的入口 main() 函数所在的包(package)叫 main,main 包想要引用别的代码,必须同样以包的方式进行引用,本章内容将 ...

  8. Go第四篇之流程控制

    流程控制是每种编程语言控制逻辑走向和执行次序的重要部分,流程控制可以说是一门语言的“经脉”. Go 语言的常用流程控制有 if 和 for,而 switch 和 goto 主要是为了简化代码.降低重复 ...

  9. Mysql相关问题收集

    1.查询每个班级的前三名 DROP TABLE IF EXISTS `sc`; CREATE TABLE `sc` ( `id` ) NOT NULL AUTO_INCREMENT, `name` v ...

  10. JavaScript new return 类的实例化

    new初始化方法 简单没有return的就不写了 function Person() { this.name="hongda"; ; return "fffffff&qu ...