10.20-导航控制器Navigation ViewController
今天模仿着老师写了一个导航控制器,初步了解了导航控制器的一些属性和行为。
1.首先是创建和加载导航控制器: 我是在程序启动时,将导航控制器作为window的根视图控制器创建和加载的,代码如下
AppDelegate.m :
1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 2 // Override point for customization after application launch. 3 4 //创建窗口对象。每个AppDelegate有一个window属性。执行完该方法,即程序启动之后,如果该window属性仍然为空,则会查看AppDelegate的配置信息,去storyboard中加载window和其根视图控制器。 5 _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 6 7 ViewController *viewCtrl = [[ViewController alloc] init]; 8 viewCtrl.title = @"Page1"; 9 10 //用一个视图控制器来初始化一个导航控制器。此时这个视图控制器将成为导航控制器的根视图控制器。 11 UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:viewCtrl]; 12 //设置导航控制器的导航条的背景颜色 13 navCtrl.navigationBar.backgroundColor = [UIColor greenColor]; 14 15 //一个窗口也需要有根视图控制器,这里设置的是一个导航控制器。 16 _window.rootViewController = navCtrl; 17 18 //显示窗口 19 [_window makeKeyAndVisible]; 20 21 return YES; 22 }
2. 上面的方法执行完后,由于导航控制器的根视图控制器的view属性仍然是空,如果ViewController(即根视图控制器对象所属的类)实现了loadView方法,就调用该实现的loadView方法,该方法应该设置view属性。如果没有实现,就调用UIViewController中的loadView方法,也会设置该view属性。 loadView执行完后,将调用viewDidLoad来加载view和其他的一些视图。注意是加载,还并没有显示,需要通过viewWillAppear: , viewWillLayoutSubviews, viewDidLayoutSubviews 和 viewDidAppear: 方法等几个步骤来显示根视图 和 子视图。可以在这些方法中进行一些显示前的动作。以下是ViewController.m中的代码实现:
ViewController.m
1 - (void)viewDidLoad { 2 [super viewDidLoad]; 3 // Do any additional setup after loading the view, typically from a nib. 4 printf("%s", __func__); 5 self.view.backgroundColor = [UIColor whiteColor]; 6 7 UIButton *pushButton = [UIButton buttonWithType:UIButtonTypeSystem]; 8 [pushButton setTitle:@"Push" forState:UIControlStateNormal]; 9 pushButton.frame = CGRectMake(0, 100, 50, 30); 10 pushButton.backgroundColor = [UIColor redColor]; 11 [pushButton addTarget:self action:@selector(didPushClicked:) forControlEvents:UIControlEventTouchUpInside]; 12 [self.view addSubview:pushButton]; 13 14 UIButton *popButton = [UIButton buttonWithType:UIButtonTypeSystem]; 15 [popButton setTitle:@"Pop" forState:UIControlStateNormal]; 16 popButton.frame = CGRectMake(100, 100, 50, 30); 17 popButton.backgroundColor = [UIColor redColor]; 18 [popButton addTarget:self action:@selector(didPopClicked:) forControlEvents:UIControlEventTouchUpInside]; 19 [self.view addSubview:popButton]; 20 21 UIButton *rootBackButton = [UIButton buttonWithType:UIButtonTypeSystem]; 22 [rootBackButton setTitle:@"RootBack" forState:UIControlStateNormal]; 23 rootBackButton.frame = CGRectMake(100, 200, 80, 30); 24 rootBackButton.backgroundColor = [UIColor redColor]; 25 [rootBackButton addTarget:self action:@selector(didRootBackClicked:) forControlEvents:UIControlEventTouchUpInside]; 26 [self.view addSubview:rootBackButton]; 27 28 //设置导航条内容 29 [self navItem]; 30 31 //设置工具条内容 32 [self toolBar]; 33 } 34 35 - (void)didReceiveMemoryWarning { 36 [super didReceiveMemoryWarning]; 37 // Dispose of any resources that can be recreated. 38 } 39 40 - (void)navItem 41 { 42 //设置导航条内容,一个导航控制器只有一个导航条和工具条,该导航控制器下的所有视图控制器共用这一个导航条和工具条。但各个视图控制器都可以改变导航条和工具条的内容。每次跳转到一个视图控制器,将刷新导航条和工具条的内容。 43 44 //导航条分为三个部分:左边部分leftBarButtonItem或leftBarButtonItems,中间部分titleView, 右边部分rightBarButtonItem 或 rightBarButtonItems。 45 //设置左边部分,是UIBarButtonItem对象,这里只设置了一个对象,但是可以设置多个对象,加到leftBarButtonItems数组中,显示时会依次显示。注意,发现这些对象不能设置尺寸大小。 46 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(didNavigationItemLeft:)]; 47 48 //设置右边部分。 49 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Right" style:UIBarButtonItemStylePlain target:self action:@selector(didNavigationItemRight:)]; 50 51 //设置中间titleView部分, titleView是一个UIView对象, 导航条的高度默认是44px,因此如果titleView的高度超过了导航条的高度,将从上下两个方向延伸出去。titleView总是在导航条中居中的,因此x,y坐标没有意义。 52 self.navigationItem.titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 44)]; 53 self.navigationItem.titleView.backgroundColor = [UIColor redColor]; 54 55 //设置导航条标题, 如果设置了titleView部分,将覆盖导航条的title。 56 self.navigationItem.title = @"title"; 57 58 //设置一些提示信息,这个部分将在导航条的上方显示,这时导航条将下移。 59 self.navigationItem.prompt = @"提示消息"; 60 } 61 62 - (void)toolBar 63 { 64 //设置工具条中包含的元素 65 UIBarButtonItem *Item0 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(didToolbarItemItem0:)]; 66 67 //生成一个占位的空白元素 68 UIBarButtonItem *FlexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 69 70 UIBarButtonItem *Item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(didToolbarItemItem1:)]; 71 72 UIBarButtonItem *Item2 = [[UIBarButtonItem alloc] initWithTitle:@"Tool" style:(UIBarButtonItemStyleDone) target:self action:@selector(didToolbarItemItem1:)]; 73 //给工具条添加对象,注意导航控制器的工具条默认是隐藏的,因此要显示工具条的话必须将其隐藏的属性关闭。 74 self.navigationController.toolbarHidden = NO; 75 self.toolbarItems = @[Item0, FlexibleSpace, Item1, FlexibleSpace, Item2]; 76 //[self setToolbarItems: @[Item0, FlexibleSpace, Item1, FlexibleSpace, Item2]]; 77 } 78 79 - (void)didPushClicked:(id)sender 80 { 81 ViewController *viewCtrl = [[ViewController alloc] init]; 82 //跳转到下一个页面,需要通过导航控制器来调用。每个控制器都有一个navigationController的属性,存储其所属的导航控制器。如果一个控制器没有处在导航控制器的控制之下,那么这个属性为nil。如果一个视图控制器viewCtrl1被另一个处在导航控制器的控制之下的视图控制器viewCtrl2通过下面这个方法跳转进来,那么viewCtrl1也自然处在了导航控制器之下了。 83 [self.navigationController pushViewController:viewCtrl animated:YES]; //该方法会获得一个viewCtrl的强引用。 84 } 85 86 - (void)didPopClicked:(id)sender 87 { 88 //跳回到上一级的视图控制器,该方法会删除本视图控制器的一个强引用。 89 [self.navigationController popViewControllerAnimated:YES]; 90 } 91 92 - (void)didRootBackClicked:(id)sender 93 { 94 //跳回到导航控制器的根视图控制器,该方法会删除从该视图控制器回到根视图控制器的链路上的所有视图控制器的一个强引用。 95 [self.navigationController popToRootViewControllerAnimated:YES]; 96 } 97 98 - (void)dealloc 99 { 100 NSLog(@"<%p>", self); 101 } 102 103 - (void)didNavigationItemLeft:(id)sender 104 { 105 NSLog(@"%s", __func__); 106 } 107 108 - (void)didNavigationItemRight:(id)sender 109 { 110 NSLog(@"%s", __func__); 111 } 112 113 - (void)didToolbarItemItem0:(id)sender 114 { 115 NSLog(@"%s", __func__); 116 } 117 118 - (void)didToolbarItemItem1:(id)sender 119 { 120 NSLog(@"%s", __func__); 121 } 122 123 - (void)didToolbarItemItem2:(id)sender 124 { 125 NSLog(@"%s", __func__); 126 }
3. 运行程序之后,就可以点击Push按钮进入下一个视图,Pop按钮返回上一层视图,RootBack按钮返回根视图。

浙公网安备 33010602011771号