开始

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

在iOS开发过程中,通常我们会使用UINavigationController,UITabbarController等苹果提供的视图控制器来切换我们的视图。在iOS5之前,如果要自定义容器视图控制器很麻烦,比如你要考虑到子视图的生命周期,当设备旋转时的情况等,好在iOS5中苹果提供了添加视图控制器(addChildViewController)等管理视图控制器的API,这样我们就能使用此API来自定义自己的视图控制器了,这篇文章只要介绍如何使用此API实现UITabbarController的基本功能。

开始使用过UITabbarController的都知道,UITabbarController可以在多个UIViewController中切换,来显示多个界面,先来看一下层级关系:

TabbarController作为根视图,然后添加了一个ChildViewController,最后用户看到内容是ChildViewController的视图内容和底部的TabBar

首先我们新建一个新的工程,选择Single Viewapplication,启用StoryBoard,将其默认的ViewController作为ContainerViewController,然后创建两个新的ViewController,分别作为两个childViewController,这样目录中就有这些文件:

我们先进入StoryBoard拖入两个UIButton,给两个button设置tag:

然后创建两个ViewController,这里我启用了xib,设置一下ViewController的背景色:

这里我一个设置了绿色,还有个设置了棕色,还分别在每个ViewController上添加了UILabel,用于区分

然后进入ContainerViewController.m,声明以下私有变量和方法:

@interfaceContainerViewController () {

FirstViewController*_firstViewController;

SecondViewController*_secondViewController;NSMutableArray*_viewControllers;

}

- (IBAction)buttonTouched:(id)sender;

FirstViewController和SecondViewController是两个ChildViewController,_viewControllers则是保存ChildViewController的数组,再去StoryBoard关联下点击事件

在viewDidLoad中初始化:

- (void)viewDidLoad

{

[super viewDidLoad];

_viewControllers=[@[] mutableCopy];

_firstViewController= [[FirstViewController alloc] initWithNibName:@"FirstViewController"bundle:nil];

_secondViewController= [[SecondViewController alloc] initWithNibName:@"SecondViewController"bundle:nil];

[_viewControllers addObject:_firstViewController];

[_viewControllers addObject:_secondViewController];

[self loadViewControllerAtIndex:0];

}

实例化了两个ViewController,然后将两个ViewController添加至数组中

关键部分来了,loadViewControllerAtIndex用于切换视图控制器,以下是实现:

- (void)loadViewControllerAtIndex:(NSInteger)index {

NSInteger nextIndex=0;if(index ==0) {

nextIndex=1;

}elseif(index ==1) {

nextIndex=0;

}

UIViewController*fromViewController =_viewControllers[nextIndex];// 获取当前viewController

UIViewController*toViewController =_viewControllers[index];// 获取将要切换的viewController

//if(self.childViewControllers.firstObject ==toViewController) {return;

}if(self.childViewControllers.count >0) {

self.view.userInteractionEnabled=NO;// 切换过程中禁用操作,等切换动画结束后恢复

[fromViewController willMoveToParentViewController:nil];// fromViewController将要移除

[self addChildViewController:toViewController];// 将toViewController添加至ContainerViewController

// 设置view的frameif(index ==1) {

toViewController.view.frame=[self nextViewStartFrame];

}else{

toViewController.view.frame=[selfPReViewStartFrame];

}

// 官方提供的切换动画API,在这里执行切换动画

[self transitionFromViewController:fromViewController toViewController:toViewController duration:0.25options:UIViewAnimationOptionCurveEaseInOut animations:^{

// 执行动画if(index ==1) {

fromViewController.view.frame=[self preViewStartFrame];

toViewController.view.frame=[self newViewStartFrame];

}else{

fromViewController.view.frame=[self nextViewStartFrame];

toViewController.view.frame=[self newViewStartFrame];

}

} completion:^(BOOL finished) {

// 动画执行完毕,从父视图添加或移除层级关系if(finished) {

[toViewController didMoveToParentViewController:self];

[fromViewController removeFromParentViewController];

self.view.userInteractionEnabled=YES;

}

}];

}else{

[self addChildViewController:toViewController];

[self.view addSubview:toViewController.view];

[toViewController didMoveToParentViewController:self];

}

}

- (CGRect)newViewStartFrame {

returnCGRectMake(0.0,0.0,320.0,500.0);

}

- (CGRect)nextViewStartFrame {

returnCGRectMake(320.0,0.0,320.0,500.0);

}

- (CGRect)preViewStartFrame {

returnCGRectMake(-320.0,0.0,320.0,500.0);

}

这个函数用于切换视图,使用addChildViewController把要添加的ViewController添加至ContainerViewController,移除不需要显示的。添加一个ViewController有几个步骤:

1. [self addChildViewController:toViewController];添加至当前viewController

2. [self.view addSubView:toViewController.view]; 添加view至self.view中

3. [toViewController didMoveToParentViewController:self];当添加完成后要调用此方法来告知已经移动到父视图控制器中

移除一个ViewController也有几个步骤:

1. [fromViewController willMoveToParentViewController:nil];参数传入nil说明将要移除视图

2. [fromViewController.view removeFromSuperView];从父视图中移除fromViewController.view

3. [fromViewController removeFromParentViewController];将fromViewController从父视图层级中移除

想要添加和移除ViewController这几个步骤是必要的,但是这里由于使用了transitionFromViewController:toViewController:duration:options:animations:completion:这个方法,它会先将toViewController.view添加至superView,然后执行动画,所以省略了[self.view addSubView:toViewController.view]

这样切换函数就算完成了,然后我们实现按钮事件函数:

- (IBAction)buttonTouched:(id)sender {if(((UIButton *)sender).tag ==1) {

[self loadViewControllerAtIndex:0];

}else{

[self loadViewControllerAtIndex:1];

}

}

点击不同的按钮切换不同的界面,最后运行效果如下:

这里只是大致实现了下切换效果,在iOS7中新增的UIViewControllerContextTransitioning和UIViewControllerAnimatedTransitioning增强了对自定义的切换,这篇文章做了详细说明http://objccn.io/issue-12-3/

demo:https://github.com/mzds/ContainHolder/tree/master

参考:https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiphoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航