UINavigationController - BNR
继续上篇UITableView的编辑操作。
当你初始化一个UINavigationController对象时,它将拥有一个根视图控制器,即UIViewController。根视图控制器一直存在于stack的底部。
UINavigationController有一个viewControllers数组属性,根视图控制器位于该数组的第一个。
UINavigationController的topViewController属性是一个指向stack顶部视图控制器的指针。
UINavigationController有自己的view属性,该view总是包含两个子视图,为UInavigationBar和topViewController的view。
在该程序中,我们将BNRItemsViewController作为UINavigationController的rootViewController。将一个navigation controller作为window的rootViewController。
修改application:didFinishLaunchingWithOptions:方法如下:
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 2 // Override point for customization after application launch. 3 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 4 BNRItemsViewController *itemsViewController = [[BNRItemsViewController alloc] init]; 5 6 UINavigationController *navController = [[UINavigationController alloc] 7 initWithRootViewController:itemsViewController]; 8 9 10 self.window.rootViewController = navController; 11 self.window.backgroundColor = [UIColor whiteColor]; 12 [self.window makeKeyAndVisible]; 13 return YES; 14 }
创建一个新的、带XIB的视图控制器名为BNRDetailViewController。
在程序中,当用户点击一个item时,将转换到另一个可编辑item信息的视图中,该新的视图就由BNRDetailViewController控制。
修改BNRDetailViewController.xib文件如下:
其中,该view的Attributes Inspector的Simulated Metrics设置如下。主要将Top Bar设置为Translucent Navigation Bar。
为3个UITextField和最后的UILabel与在BNRDetailViewController.m的类扩展中的outlet建立连接。如下:
当你改变实例变量的名字,而没有更新XIB文件中的连接时,就会出现一个坏连接。或者,你完全删除了一个实例变量,但是没有在XIB文件中删除时也会出现坏连接。
接下类,将XIB文件的每一个UITextField对象,通过Control-Drag与File's Owner的delegate属性相连接。如下所示:
在BNRItemsViewController.m中导入BNRDetailViewController,如下:
#import "BNRDetailViewController.h"
当用户在表视图中点击了一行时,它的委托对象会接收到tableView:didSelectRowAtIndexPath:方法。因此在BNRItemsViewController.m中添加如下代码,当用户点击一行时,会出现编辑视图:
1 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 2 BNRDetailViewController *detailViewController = [[BNRDetailViewController alloc] init]; 3 [self.navigationController pushViewController:detailViewController animated:YES]; 4 }
将item的数据传递到下一个视图中:
在BNRDetailViewController.h中添加如下属性:
@property (nonatomic, strong) BNRItem *item;
同时,在@interface前面,用如下代码引入BNRItem类:
@class BNRItem;
在BNRDetailViewController.m中导入BNRItem,如下:
#import "BNRItem.h"
当BNRDetailViewController的view在屏幕上显示的时候,它需要设置其子视图来显示item的属性。重写viewWillAppear:方法如下:
1 - (void)viewWillAppear:(BOOL)animated { 2 [super viewWillAppear:animated]; 3 BNRItem *item = self.item; 4 self.nameField.text = item.itemName; 5 self.serialNumberField.text = item.serialNumber; 6 self.valueField.text = [NSString stringWithFormat:@"%d", item.valueInDollars]; 7 8 static NSDateFormatter *dateFormatter = nil; 9 if (!dateFormatter) { 10 dateFormatter = [[NSDateFormatter alloc] init]; 11 dateFormatter.dateStyle = NSDateFormatterMediumStyle; 12 dateFormatter.timeStyle = NSDateFormatterNoStyle; 13 } 14 self.dateLabel.text = [dateFormatter stringFromDate:item.dateCreated]; 15 }
之后,修改tableView:didSelectRowAtIndexPath:方法如下:
1 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 2 BNRDetailViewController *detailViewController = [[BNRDetailViewController alloc] init]; 3 NSArray *items = [[BNRItemStore sharedStore] allItems]; 4 BNRItem *selectedItem = items[indexPath.row]; 5 detailViewController.item = selectedItem; 6 7 [self.navigationController pushViewController:detailViewController animated:YES]; 8 }
在BNRDetailViewController.m中添加如下代码:
1 - (void)viewWillDisappear:(BOOL)animated { 2 [super viewWillDisappear:animated]; 3 [self.view endEditing:YES]; 4 // 保存更改 5 BNRItem *item = self.item; 6 item.itemName = self.nameField.text; 7 item.serialNumber = self.serialNumberField.text; 8 item.valueInDollars = [self.valueField.text intValue]; 9 }
需要重新加载UITableView,这个用户就可以看到内容的改变了。即在BNRItemsViewController.m中添加如下代码:
1 - (void)viewWillAppear:(BOOL)animated { 2 [super viewWillAppear:animated]; 3 [self.tableView reloadData]; 4 }
修改导航栏:
打开BNRItemsViewController.m,修改视图控制器navigationItem的标题,可修改init方法如下:
1 - (instancetype)init { 2 self = [super initWithStyle:UITableViewStylePlain]; 3 if (self) { 4 UINavigationItem *navItem = self.navigationItem; 5 navItem.title = @"Homepwner"; 6 // 添加5个随机item 7 for (int i = 0; i < 5; ++i) { 8 [[BNRItemStore sharedStore] createItem]; 9 } 10 } 11 return self; 12 }
打开BNRDetailViewController.m,修改器标题,可添加如下方法:
1 - (void)setItem:(BNRItem *)item { 2 _item = item; 3 self.navigationItem.title = _item.itemName; 4 }
对于每一个UINavigationView,其属性有:leftBarButtonItem,rightBarButtonItem和titleView。
在BNRItemsViewController.m中创建UIBarButtonItem对象,并且赋予target和action,即修改init方法如下:
1 - (instancetype)init { 2 self = [super initWithStyle:UITableViewStylePlain]; 3 if (self) { 4 UINavigationItem *navItem = self.navigationItem; 5 navItem.title = @"Homepwner"; 6 7 UIBarButtonItem *bbi = [[UIBarButtonItem alloc] 8 initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 9 target:self 10 action:@selector(addNewItem:)]; 11 navItem.rightBarButtonItem = bbi; 12 navItem.leftBarButtonItem = self.editButtonItem; 13 // 添加5个随机item 14 for (int i = 0; i < 5; ++i) { 15 [[BNRItemStore sharedStore] createItem]; 16 } 17 } 18 return self; 19 }
UIViewController有一个editButtonItem属性。当发送editButtonItem时,视图控制器就会创建一个title为Edit的UIBarButtonItem。当被用户点击时,其会发送setEditing:animated:方法给UIViewController。
在BNRItemsViewController.m文件中,注释掉headerView和toggleEditingMode:方法。
运行程序,结果如下: