在平时开发中,利用导航控制器进行push和pop完成界面的跳转,是最常见的一种方式。今天就对导航控制器的一些知识盲点进行了一个小结。
首先, 对下面三个类的比较:
UINavigationBar :继承至UIView,NavigationBar就是导航栏,位于屏幕的上方,管理整个NavigationController的navigationItem,即类似navigationcontroller一样提供了一个栈来管理item。
UINavigationItem : 继承至NSObject,通过这个属性来设置title ,leftBarButtonItem,titleView,,rightBarButtonItem,backBarButonItem 等。
UIBarButtonItem :继承至UIBarItem,UIBarItem继承至UIButton。专门用来放在UIToolbar 或者 UINavigationBar的特殊button。
另外,UINavigationBar的两个属性进行了比较:
1. topViewController 栈顶的控制器
2. visibleViewController 当前屏幕上可见的viewController,包括modal出来的controller
NSArray *stackViewControllers =self.navigationController.viewControllers;
区别:topViewController一定是栈中的控制器,在stackViewControllers数组中。而如果在某个push完成的controller中present出一个viewController2,此时topViewController还是viewController,而visibleViewController就变成viewController1了。
关于通过导航控制器的跳转方式:
一.push
二.pop(1.逐级pop 2.跳跃式pop 3.pop到栈底)
下面是跳转到上一级controller并回传参数的代码:
- (void)setPopItem{
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回到上一级" style:UIBarButtonItemStylePlain target:self action:@selector(pop)];
}
- (void)pop{
NSArray *viewControllers = self.navigationController.viewControllers;
NSInteger preVCIndex = viewControllers.count - 2;
NSLog(@"栈底%@,栈顶%@",[viewControllers firstObject],[viewControllers lastObject]);
if (preVCIndex >= 0) {
UIViewController *preVC = [self.navigationController.viewControllers objectAtIndex:preVCIndex];
if ([preVC isKindOfClass:[RemindViewController class]]) {
RemindViewController* vcn1 = (RemindViewController *) preVC;
vcn1.popInt = 3; // 传参
}
[self.navigationController popToViewController:preVC animated:YES];
}
}
总结: int count = self.navigationController.viewControllers.count;
viewControllers数组中从index=0到index =count-1对应着栈底到栈顶的controller。如firstObject对应数组中第一个元素,即栈底的控制器:lastObject对应对应数组中最后一个元素,就是当前正在屏幕上显示的栈顶的controller。