这篇文章介绍使用UINavigationController切换视图。这个Navigation Controller功能强大,主要用来切换多级的视图。可以将Navigation Controller理解成一个栈,这个栈中可以存放很多View Controller。在这个栈创建的时候,我们先给它添加一个View Controller,称为Root View Controller,它放在栈底,代表的是刚加载程序的时候显示的视图。当用户新选择了一个想要显示的视图时,那个新的View Controller入栈,它所控制的视图就会显示出来。这个新的View Controller通常称作Sub Controller。

进入一个新的视图后,左上方会出现一个按钮,叫做Navigation Button,它就像浏览器的后退按钮一样,点击此按钮,当前的View Controller出栈,之前的View就会显示。

这种设计模式使得开发变得简单,我们只需知道每一个View Controller的Sub Controller就好了。

我们这次要做的小例子运行如下图:

左边的图片是刚运行时显示的效果,它是一个表格,表格中的每一行代表不通过的View Controller。注意到每一行的右边有一个图标,叫做Disclosure Indicator,它用来告诉用户单击这一行会进入另一个视图。当点击某行,就进入中间图片显示的视图。中间图片中,左上角的按钮就是Navigation Button。中间的图片中,每一行右边有一个按钮,叫做Detail Disclosure Button,它不仅仅是一个图标,实际上它是一个控件,用户点击它会进入该行的详细说明。点击某行的Detail Disclosure Button,进入相应的视图,如右边的图片。

为了更好地理解Navigation Controller的原理,我们从Empty Application开始我们的小例子。

1、运行Xcode 4.2,新建一个Empty Application,名称为:Navigation Controller Test:

2、创建一个View Controller,作为Root View Controller:依次选择File——New——New File,在弹出的窗口,左边选择iOS下的Cocoa Touch,右边选择UIViewController subclass:

单击Next,在新窗口输入名称为RootViewController,sub of选择UItableViewController:

之后选好位置,完成创建。

3、打开AppDelegate.h,向其中添加属性:

@property (strong, nonatomic) UINavigationController *navController;

然后打开AppDelegate.m,在@implementation之前添加代码:

#import "RootViewController.h"

在@synthesize window = _window;之后添加代码:

@synthesize navController;#pragma mark -
#pragma mark Application lifecycle

在didFinishLaunchingWithOptions方法中添加代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];// Override point for customization after application launch.RootViewController *root = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; self.navController = [[UINavigationController alloc] initWithRootViewController:root]; [self.window addSubview:navController.view];self.window.backgroundColor = [UIColor whiteColor];[self.window makeKeyAndVisible];return YES;
}

4、我们先要明确,Root View Controller中是一个表格,它的每一行对应一个Sub View Controller。

打开RootViewController.h,添加属性:

@property (strong, nonatomic) NSArray *controllerList;

打开RootViewController.m,在@implementation之后添加代码:

@synthesize controllerList;

在viewDidLoad中[super viewDidLoad];之后添加代码:

self.title = @"分类";
NSMutableArray *array = [[NSMutableArray alloc] init];
self.controllerList = array;

在ViewDidUnload方法中添加代码:

self.controllerList = nil;

找到numberOfSectionsInTableView方法,修改其返回值为1。

找到numberOfRowsInSection:方法,修改代码为:

return [controllerList count];

找到cellForRowAtIndexPath方法,修改其中代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{static NSString *RootTableViewCell = @"RootTableViewCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: RootTableViewCell]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier: RootTableViewCell]; } NSUInteger row = [indexPath row]; UITableViewController *controller = [controllerList objectAtIndex:row]; //这里设置每一行显示的文本为所对应的View Controller的标题cell.textLabel.text = controller.title;//accessoryType就表示每行右边的图标cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell;
}

找到didSelectRowAtIndexPath:方法,修改其中代码如下:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{NSUInteger row = [indexPath row]; UITableViewController *nextController = [self.controllerList objectAtIndex:row]; [self.navigationController pushViewController:nextController animated:YES];
}

5、现在为止,我们还看不到什么效果,那是因为controllerList这个数组现在是空的。

接下来我们创建一个Table View Controller,用于显示电影列表。建立的方法同建立RootViewController一样,名称为:MovieViewController。

之后再创建一个View Controller,名称为MovieDetailViewController,用于显示电影的详细信息,这次我们要选中include xib file…选项,并且Subof选项为UIViewController:

6、打开MovieDetailViewController.xib,拖一个Label到中间,并拉长。将其映射到MovieDetailViewController.h中,名称为detailLabel:

然后在MovieDetailViewController.h中添加属性:

@property (copy, nonatomic) NSString *message;

打开MovieDetailViewController.m,在@implementation之后添加代码:

@synthesize message;

在viewDidLoad方法后面添加一个方法:

- (void)viewWillAppear:(BOOL)animated { detailLabel.text = message; [super viewWillAppear:animated];
}

viewWillAppear这个方法每次视图加载都会执行,而viewDidLoad方法只有在第一次加载时才会执行。

在viewDidUnload方法中添加代码:

self.detailLabel = nil;
self.message = nil;

7、打开MovieViewController.h,向其中添加属性:

@property (strong, nonatomic) NSArray *movieList;

打开MovieViewController.m,在@implementation之前添加代码:

#import "MovieDetailViewController.h"
#import "AppDelegate.h"
@interface MovieViewController ()
@property (strong, nonatomic) MovieDetailViewController *childController;
@end

在@implementation之后添加代码:

@synthesize movieList;
@synthesize childController;

在viewDidLoad方法中添加代码:

NSArray *array = [[NSArray alloc] initWithObjects:@"肖申克的救赎", @"教父", @"教父:II",@"低俗小说", @"黄金三镖客", @"十二怒汉", @"辛德勒名单",@"蝙蝠侠前传2:黑暗骑士", @"指环王:王者归来", @"飞越疯人院",@"星球大战Ⅴ:帝国反击战", @"搏击俱乐部", @"盗梦空间", @"七武士",@"指环王:护戒使者", @"好家伙", @"星球大战IV:新希望", @"上帝之城",@"卡萨布兰卡", @"黑客帝国", @"西部往事", @"后窗", @"夺宝奇兵",@"沉默的羔羊", @"非常嫌疑犯", @"七宗罪", @"指环王:双塔奇兵", @"阿甘正传",@"惊魂记", @"美好人生", nil];
self.movieList = array;

在ViewDidUnload方法中添加代码:

self.movieList = nil;
self.childController = nil;

找到numberOfSectionsInTableView方法,修改其返回值为1。

找到numberOfRowsInSection:方法,修改代码为:

return [movieList count];

找到cellForRowAtIndexPath方法,修改其中代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{static NSString *MovieTableViewCell = @"MovieTableViewCell"; UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier: MovieTableViewCell]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier: MovieTableViewCell]; } NSUInteger row = [indexPath row]; NSString *movieTitle = [movieList objectAtIndex:row];//这里设置每一行显示的文本为所对应的View Controller的标题cell.textLabel.text = movieTitle;//accessoryType就表示每行右边的图标cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; return cell;
}

修改didSelectRowAtIndexPath方法:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

在@end之前添加方法:

- (void)tableView:(UITableView *)tableViewaccessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { if (childController == nil) { childController = [[MovieDetailViewController alloc]initWithNibName:@"MovieDetailViewController" bundle:nil]; } NSUInteger row = [indexPath row]; NSString *selectedMovie = [movieList objectAtIndex:row]; NSString *detailMessage = [[NSString alloc]initWithFormat:@"你选择了电影:%@.", selectedMovie]; childController.message = detailMessage; childController.title = selectedMovie; [self.navigationController pushViewController:childController animated:YES];
}

8、打开RootViewController.m,在@implementation之前添加代码:

#import "MovieViewController.h"

在viewDidLoad方法中self.controllerList = array;之前添加代码:

//电影
MovieViewController *movieViewController = [[MovieViewController alloc]initWithStyle:UITableViewStylePlain];
movieViewController.title = @"电影";
[array addObject:movieViewController];

9、运行一下:

RootViewController表格中其他选项的实现跟上面是类似的,重复操作比较多,不再讲了。

总的来说,Navigation Controller还是很强大的。使用的时候把它想象成一个栈,用起来就会比较简单。

来源:http://my.oschina.net/plumsoft/blog/52975

附上: Master-Detail Application 版的代码: StarWars.zip (xcode 4.3)

附上: Empty Application 版的代码 NavigationController-Tableview.zip(xcode 4.3)

视频:http://www.youtube.com/watch?v=h72ydCiIwLg&feature=plcp&context=C4da2e12VDvjVQa1PpcFPlH7OSz8KtLBvah_bDxdE86kasYQU9OuI%3D

UITableView 系列二 :资料的设定方式 (Navigation Controller切换视图) (实例)相关推荐

  1. UITableView 系列四 :项目中行的操作 (添加移动和删除)(实例)

    这篇文章主要讲的表格的操作包括:标记行.移动行.删除行.插入行. 这次就不从头建立工程了,在http://dl.iteye.com/topics/download/441cdcca-3191-321b ...

  2. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能

    Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...

  3. Wireshark入门与进阶系列(二)

    摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) "君子生非异也,善假于物也&quo ...

  4. [知识库分享系列] 二、.NET(ASP.NET)

    最近时间又有了新的想法,当我用新的眼光在整理一些很老的知识库时,发现很多东西都已经过时,或者是很基础很零碎的知识点.如果分享出去大家不看倒好,更担心的是会误人子弟,但为了保证此系列的完整,还是选择分享 ...

  5. 软件开发随笔系列二——关于架构和模型

    软件开发随笔系列二--关于架构和模型 文章目录 软件开发随笔系列二--关于架构和模型 软件模型 功能模型 概念层 边界 参与方 分组分类 逻辑层 功能组织图 层次.模块化 接口 流程模型 概念层 业务 ...

  6. 微服务架构系列二:密码强度评测的实现与实验

    本文是继<微服务架构系列一:关键技术与原理研究>的后续,系列一中论述了微服务研究的背景和意义,主要调研了传统架构的发展以及存在的问题和微服务架构的由来,然后针对微服务架构的设计原则.容器技 ...

  7. UITableView 系列三 :分类显示和改变外观 (实例)

    1. 分类显示 sections 在之前的文章UITableView 的资料设定方式一文中,已经示范如何在 UITableView 中设定所要显示的资料,以及分别显示这些资料的细节,但是如果资料比数太 ...

  8. UITableView 系列一 :基本使用方法 (显示,删除,添加图片,添加样式等) (实例)...

    基本概念: 1. UITableView 的 Style 预设有两种:Plain 及 Grouped. Plain: Grouped: 2. 装在 UITableView 里面的元素是 UITable ...

  9. Linux学习系列二:Linux中的常用命令

    这个系列的Linux教程主要参考刘遄老师的<Linux就该这么学>.用的系统是RHEL8,如果遇见一些命令出现问题,请首先检查自己的系统是否一致,如果不一致,可网上查一下系统间某些命令之间 ...

最新文章

  1. java中Class.forName与new
  2. matlab dividend,[原创]基于(Matlab/R/C++)的方差Gamma模型(Hull期权期货)随机抽样[by fantuanxiaot]...
  3. ucharts 折线 点_ucharts图表引入的两种方式
  4. python爬虫什么书好_python爬虫入门06 | 爬取当当网 Top 500 本五星好评书籍
  5. linux环境c语言编程 蔡晋,Linux环境C语言编程
  6. 图像处理:透镜畸变及校正模型
  7. Java 多版本JDK 环境配置 javac和java 版本不一致
  8. 特征的标准化和归一化
  9. php 微信公众号客服,微信公众平台开发多客服
  10. 解决Connectify和校园天翼宽带L2TP客户端的不兼容问题
  11. 因多次登录失败导致的账户锁定,ssh无法登录处理
  12. OpenStack柏林峰会主会场侧记:OpenStack立柱、拱券与灵魂
  13. C# App.config 自定义 配置节 报错“配置系统未能初始化” 解决方法
  14. 【Andriod Studio实现拨打电话和发送短信功能】
  15. 什么是第三方支付?第三方支付流程
  16. 【原创】软件测试(原书第二版)
  17. 奥克兰理工大学计算机学院,9月17日学术报告(新西兰奥克兰理工大学 Prof. Re
  18. 专访「算法之父」Michael Saunders:人工智能未来的突破点可能在自动驾驶
  19. 平板android10英寸,华硕推出8/10英寸ZenPad Android平板新品
  20. java-php-python-ssm文献管理平台计算机毕业设计

热门文章

  1. 统计问题(HDU-2563)
  2. 单词替换(信息学奥赛一本通-T1406)
  3. 高级语言中的关键字:const用法分析
  4. 降维:用 PCA 压缩数据集
  5. Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level
  6. 如何写一篇合格的论文(清华大学刘知远)
  7. 3-1HDFS基本概念
  8. [有限元] DistMesh Matlab 程序示例
  9. 插件设置修改失败_【王者荣耀金牌特权】详细技术设置教程,更新异常解决办法...
  10. ubuntu croncab定时任务 shell脚本单独可行 定时任务执行命令不可行