导航控制器初始化的时候一般都有一个根视图控制器
UINavigationController *navc = [[UINavigationController alloc]initWithRootViewController:(nonnull UIViewController *)];
导航控制器相当于一个栈 我们要在栈中新增或者删除一个导航控制器 ,就要得到导航控制器, 一般在栈中的所有视图控制器都有一个self.navigationController , 意思是我的导航控制器, 也就是这个视图控制器所在的导航控制器, 这样就拿到了导航控制器
栈中新增视图控制器 对于用户而言打开了一个新的界面
SecondViewController *secondVc = [[SecondViewController alloc]init];
[self.navigationController pushViewController:secondVc animated:YES];
栈中删除视图控制器 对于用户而言就是从当前视图回到上一级视图
[self.navigationController popViewControllerAnimated:YES];
事实上这个push和pop对于用户而言都是打开和跳转页面的一个操作。而pop由很多其它地操作方法,如一下子pop掉仅仅剩下一个根视图控制器,那么就相当于从好几层直接回到最原始的主页面。也能够指定pop几个,以跳转到指定的页面
//能够手动设置pop出栈,相当于删除这个页面,跳转到其它页面
popViewControllerAnimated就是弹出,由于弹出仅仅能弹出最上面的栈顶的那个,所以能够不用指定參数
//popToRootViewControllerAnimated-就是直接跳转到根视图控制图,假设仅仅有两层,那么和popViewControllerAnimated并无差别,假设有非常多层,那么事实上就是相当于不仅把自己pop出去,还把全部除了根视图控制图之外的全部视图控制器都pop出去了,所以就相当于跳转到根视图控制器了
//popToViewController-就是跳转到指定的视图控制器xxx,这个xxx一定要在这个栈里面,即一定是在我们当前这个视图控制器的以下的,所以跳转也就是把自己和在xxx上面的全部视图控制器都pop出去,然后相当于直接跳转到xxx
//此处重点是这个xxx怎么获取,依照一般理解是用xxx再初始化一个视图控制器对象yyy,然后把这个对象yyy作为popToViewController参数
//但事实是,yyy是新初始化的,不在栈中,当然和在栈中的xxx初始化的那个对象也不是同一个对象,所以会报错(由于在栈中找不到啊)
//所以,self.navigationController.viewControllers出场,viewControllers是个数组,储存的时导航控制器栈中全部的视图控制器,最先push进去的时0,以此类推,最上面的肯定是数组的最后一个
//所以,那个xxx之前初始化的对象,能够用[self.navigationController.viewControllers objectAtIndex:0]表示,此处0就是根视图控制器
//所以,仅仅要拿到navigationController,貌似能做非常多事情
-(void)backTo{
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}
提到导航控制器栈的push 和 pop 不由得想到了一个小tip :
ios系统自带的控制器左边缘右滑pop出栈 这是iOS7.0之后 苹果新推出的一个小功能 就是对于UINavagationController堆栈里的UIViewController,只要轻轻在视图控制器的左边缘右滑一下,该视图控制器就会pop出栈(前提当然是对于非根视图控制器而言)。实现方法很简单,一句话搞定:
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
事实上控制器的这一属性系统默认即为YES,因此不设置也能实现右滑pop的功能。然而这个功能很有局限性,因为它不允许当前视图控制器自定义了leftBarButtonItem,一旦自定义,右滑功能就会失效。这里有两个简单的方法:
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
设置代理为nil之后即便自定义了leftBarButtonItem也可以右滑pop。
或者还有另外一个方法:
在当前界面push出来之前 把代理设置为nil 同样还是这行代码
self.navigationController.interactivePopGestureRecognizer.delegate = nil;