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

来源:互联网 发布:大连程序员工资多少 编辑:程序博客网 时间:2024/05/14 03:30

这篇文章介绍使用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,向其中添加属性:

C代码 复制代码 收藏代码
  1. @property (strong, nonatomic) UINavigationController *navController;  
 

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

C代码 复制代码 收藏代码
  1. #import "RootViewController.h"  
 

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

C代码 复制代码 收藏代码
  1. @synthesize navController;   
  2.   
  3. #pragma mark -    
  4. #pragma mark Application lifecycle  
 

在didFinishLaunchingWithOptions方法中添加代码:

C代码 复制代码 收藏代码
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions   
  2. {   
  3.     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];   
  4.     // Override point for customization after application launch.  
  5.        
  6.     RootViewController *root = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];    
  7.     self.navController = [[UINavigationController alloc] initWithRootViewController:root];    
  8.     [self.window addSubview:navController.view];   
  9.        
  10.     self.window.backgroundColor = [UIColor whiteColor];   
  11.     [self.window makeKeyAndVisible];   
  12.     return YES;   
  13. }  
 

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

 

打开RootViewController.h,添加属性:

C代码 复制代码 收藏代码
  1. @property (strong, nonatomic) NSArray *controllerList;  
 

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

C代码 复制代码 收藏代码
  1. @synthesize controllerList;  
 

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

C代码 复制代码 收藏代码
  1. self.title = @"分类";    
  2. NSMutableArray *array = [[NSMutableArray alloc] init];    
  3. self.controllerList = array;  
 

在ViewDidUnload方法中添加代码:

C代码 复制代码 收藏代码
  1. self.controllerList = nil;  
 

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

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

C代码 复制代码 收藏代码
  1. return [controllerList count];  
 

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

C代码 复制代码 收藏代码
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath   
  2. {   
  3.     static NSString *RootTableViewCell = @"RootTableViewCell";    
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: RootTableViewCell];    
  5.     if (cell == nil) {    
  6.         cell = [[UITableViewCell alloc]    
  7.                 initWithStyle:UITableViewCellStyleDefault   
  8.                 reuseIdentifier: RootTableViewCell];    
  9.     }    
  10.     NSUInteger row = [indexPath row];    
  11.     UITableViewController *controller = [controllerList objectAtIndex:row];    
  12.     //这里设置每一行显示的文本为所对应的View Controller的标题   
  13.     cell.textLabel.text = controller.title;   
  14.     //accessoryType就表示每行右边的图标   
  15.     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;    
  16.     return cell;    
  17. }  
 

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

C代码 复制代码 收藏代码
  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath   
  2. {   
  3.     NSUInteger row = [indexPath row];    
  4.     UITableViewController *nextController = [self.controllerList objectAtIndex:row];    
  5.     [self.navigationController pushViewController:nextController animated:YES];    
  6. }  
 

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

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

 

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

 

 

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

 

 

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

C代码 复制代码 收藏代码
  1. @property (copy, nonatomic) NSString *message;  
 

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

C代码 复制代码 收藏代码
  1. @synthesize message;  
 

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

C代码 复制代码 收藏代码
  1. - (void)viewWillAppear:(BOOL)animated {    
  2.     detailLabel.text = message;    
  3.     [super viewWillAppear:animated];    
  4. }  
 

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

 

在viewDidUnload方法中添加代码:

C代码 复制代码 收藏代码
  1. self.detailLabel = nil;   
  2. self.message = nil;  
 

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

C代码 复制代码 收藏代码
  1. @property (strong, nonatomic) NSArray *movieList;  
  

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

C代码 复制代码 收藏代码
  1. #import "MovieDetailViewController.h"   
  2. #import "AppDelegate.h"   
  3. @interface MovieViewController ()    
  4. @property (strong, nonatomic) MovieDetailViewController *childController;    
  5. @end  
 

在@implementation之后添加代码:

C代码 复制代码 收藏代码
  1. @synthesize movieList;   
  2. @synthesize childController;  
 

在viewDidLoad方法中添加代码:

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

在ViewDidUnload方法中添加代码:

C代码 复制代码 收藏代码
  1. self.movieList = nil;   
  2. self.childController = nil;  
 

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

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

C代码 复制代码 收藏代码
  1. return [movieList count];  
 

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

C代码 复制代码 收藏代码
  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath   
  2. {   
  3.     static NSString *MovieTableViewCell = @"MovieTableViewCell";    
  4.     UITableViewCell *cell = [tableView   
  5.                              dequeueReusableCellWithIdentifier: MovieTableViewCell];    
  6.     if (cell == nil) {    
  7.         cell = [[UITableViewCell alloc]    
  8.                 initWithStyle:UITableViewCellStyleDefault   
  9.                 reuseIdentifier: MovieTableViewCell];    
  10.     }    
  11.     NSUInteger row = [indexPath row];    
  12.     NSString *movieTitle = [movieList objectAtIndex:row];   
  13.     //这里设置每一行显示的文本为所对应的View Controller的标题   
  14.     cell.textLabel.text = movieTitle;   
  15.     //accessoryType就表示每行右边的图标   
  16.     cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;    
  17.     return cell;   
  18. }  
 

修改didSelectRowAtIndexPath方法:

C代码 复制代码 收藏代码
  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath   
  2. {   
  3.     [tableView deselectRowAtIndexPath:indexPath animated:YES];    
  4. }  
 

在@end之前添加方法:

C代码 复制代码 收藏代码
  1. - (void)tableView:(UITableView *)tableView   
  2.   accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {    
  3.     if (childController == nil) {    
  4.         childController = [[MovieDetailViewController alloc]   
  5.                            initWithNibName:@"MovieDetailViewController" bundle:nil];    
  6.     }    
  7.     NSUInteger row = [indexPath row];    
  8.     NSString *selectedMovie = [movieList objectAtIndex:row];    
  9.     NSString *detailMessage = [[NSString alloc]   
  10.                                initWithFormat:@"你选择了电影:%@.", selectedMovie];    
  11.     childController.message = detailMessage;    
  12.     childController.title = selectedMovie;    
  13.     [self.navigationController pushViewController:childController animated:YES];    
  14. }  
  

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

C代码 复制代码 收藏代码
  1. #import "MovieViewController.h"  
  

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

C代码 复制代码 收藏代码
  1. //电影    
  2. MovieViewController *movieViewController = [[MovieViewController alloc]   
  3.                                             initWithStyle:UITableViewStylePlain];    
  4. movieViewController.title = @"电影";     
  5. [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

 

 

 

 

  • StarWars.zip (336.1 KB)
  • 下载次数: 36
  • NavigationController-Tableview.zip (35.6 KB)
  • 下载次数: 49
原创粉丝点击