前言:注册简书也有很长时间了,但是一直在看别人写的文章,没有自己写过什么,也是觉得自己能力不够,怕写出来的一些东西太简单了,也没什么用,最近身边有个朋友,是个大神,看到他的工作和学习状态我才知道原来自己和他们差的不是经验,而是勤奋,看了他的认真态度,才知道什么叫真正的程序员,才知道为什么他能进入那些大的企业去工作,好了,废话不多说了,今天第一篇文章,写的不好大家可以留言给我,帮助我进步,感谢每一位进来读这篇文章的人。谢谢。
1.UINavigationController的功能和作用
我们都知道大部分的手机软件的框架有两种,一种是底层UITabBarController 然后用UINavigationController加在UITabBarController上面,另一种是UINavigationController作为底层控制器 UITabBarController 加在UINavigationController上面,当然我没用过第二种,我都是用的第一种。
UITabBarController我们今天先不说了,主要说一下UINavigationController,按我对于UINavigationController的理解来说,UINavigationController就是一个导航控制器,主要用来控制页面之间的跳转,举例来说UINavigationController有一个根控制器,RootViewController,其余的都算是主控制器的跟班,例如A是主控制器,那么接下来被puch出来的控制器都是他的跟班,B 、C 、D,也就是子控制器,用下面这句代码来说VC就是这个UINavigationController的根控制器
UIViewController *vc = [[UIViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
那么接下来的所有被puch 出来的UIViewController则都是VC的跟班,他们之间的关系不可以可以用层的关系来解释,如果你现在puch到了D的页面 ,那么A在最下面,上面的是B,B上面的是C,C上面的是D,此时若是调用
[self.navigationController popViewControllerAnimated:YES];
这句话的意思就是返回上一个控制器的意思,意思是把D释放掉,C就变成最上面的控制器了。
那么如果用
[self.navigationController popToRootViewControllerAnimated:YES];
这句话的意思是由D控制器直接返回到主控制器A,现在B和C还有D控制器则全部都被释放掉了。
那么此时你若由A主控制器puch到B控制器,如下代码,那么B的控制器里面的内容也需要全部重新去加载
[self.navigationController pushViewController:B animated:YES];
我们可以在B、C、D 控制下的ViewController 的 viewDidLoad 方法 ,用NSLog输出出来self.navigationController.viewControllers 这个数组 则可以很直白的看出 每当我们puch出来一个控制器的时候 ,self.navigationController.viewControllers这个数组里面的对象就会多出来一个 ,每当我们pop销毁一个控制器的时候,我们会发现self.navigationController.viewControllers这个数组的对象就会少一个。
那么问题来了,对于各种项目的需求都是千奇百怪的,我们近期的项目也有这种需求,就是当我们由主控制器A puch到控制器D 那么我要返回的时候 则是按照D-C-B-A的顺序返回,那么我们应该怎么去处理这种需求呢 ,那么我则是用了最笨的一种方法, 我用了一个循环
for (int i = 0; i <3; i++) {
[self.navigationController pushViewController:self.arrayControllers[i] animated:NO];
}
self.arrayControllers 这个数组里面放的是控制器B、C、D 这样我现在就已经把3个子控制器加到了self.navigationController.viewControllers的这个数组里面,那么当我们要做返回的时候,就会按照顺序 D-C-B-A的顺序返回,大家看到我循环里面的动画效果我用的NO,因为此时若是你用YES的话你就会发现你的页面是由一层层的推过去的 ,而不是直接出现的D的控制器画面,那这种效果产品是肯定不想看到的,而且如果是用户的话也会觉得这个程序做的太~~~草率了,所以这个地方要用NO,那么还有一点值得我们提到的就是,上面的代码虽然直接puch到D控制器了,但却不会加载B和C页面的viewDidLoad 方法,也就是说,不会影响你B和C里面初始要加载的页面以及数据,你也可以理解成为B和C都没有显示出来,但是已经加入到self.navigationController.viewControllers这个数组里面了。
那么除了这个方法还有什么方法能够解决这个问题呢,还有一个方法就是换掉self.navigationController.viewControllers这个数组里面的对象和顺序,加入此时我们在跟控制器A的页面,那么我们要puch到D在按照顺序返回 那么 此时我们应该先puch到D在替换掉self.navigationController.viewControllers这个数组
NSMutableArray *array = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
UIViewController *B = [[UIViewController alloc] init];
UIViewController *C = [[UIViewController alloc] init];
[array insertObject:B atIndex:1];
[array insertObject:C atIndex:2];
self.navigationController.viewControllers = array;
我们可以看到在没有执行上面代码之前self.navigationController.viewControllers数组里面的对象是A控制器和D控制器,执行上面代码self.navigationController.viewControllers数组的对面个则是A、B、C、D,四个控制器此时在由D返回上一层的界面则是C控制器,然后是B控制器,最后是跟控制器。
那么如果出现了这种需求怎么办 直接有D控制器pop 回B控制器 那么就会用到这种方法
int count = (int)[[self.navigationController viewControllers]indexOfObject:self];
UIViewController *vc = [self.navigationController.viewControllers objectAtIndex:(count - 2)];
[self.navigationController popToViewController:vc animated:YES];
上面的这个方法会让我们由D直接返回到B控制器
以上就是UINavigationController的一些跳转的方法,如果有写的不好的地方还请多指教