During iOS development, we usually use UINavigationController, UITabbarController, and other view controllers provided by Apple to switch our views. Before iOS5, it is difficult to customize the container View Controller. For example, you need to consider the sub-view lifecycle and the condition when the device rotates, fortunately, in iOS5, Apple provided APIs for managing view controllers, such as addChildViewController, so that we can use this API to customize our own view controllers, this article only describes how to use this API to implement basic functions of UITabbarController.
Start
Anyone who has used UITabbarController knows that UITabbarController can switch between multiple uiviewcontrollers to display multiple interfaces. First, let's look at the hierarchical relationship:
TabbarController is used as the root view, and a ChildViewController is added. At last, the user can see the view content of ChildViewController and the TabBar at the bottom.
First, create a new project, select Single View Application, enable StoryBoard, use its default ViewController as ContainerViewController, and then create two new viewcontrollers as two childviewcontrollers, in this way, these files are in the directory:
We will drag two UIButton buttons into the StoryBoard and set the tag for the two buttons:
Create two viewcontrollers. Here, xib is enabled and the background color of ViewController is set:
Here I have set the green color and the brown color respectively, and added the UILabel to each ViewController for distinguishing
Enter ContainerViewController. m and declare the following private variables and methods:
@interface ContainerViewController () { FirstViewController *_firstViewController; SecondViewController *_secondViewController; NSMutableArray *_viewControllers;}
-(IBAction) buttonTouched :( id) sender;
FirstViewController and SecondViewController are two childviewcontrollers. _ viewControllers is the array that saves ChildViewController, and then associated with the click event on the StoryBoard.
-(Void) viewDidLoad {[super viewDidLoad]; _ viewControllers = [@ [] mutableCopy]; _ firstViewController = [[FirstViewController alloc] initWithNibName: @ "FirstViewController" bundle: nil]; _ secondViewController = [[SecondViewController alloc] handler: @ "SecondViewController" bundle: nil]; [_ viewControllers addObject: _ firstViewController]; [_ viewControllers addObject: _ secondViewController]; [self loadViewControllerAtIndex: 0];}
Two viewcontrollers are instantiated, and then two viewcontrollers are added to the array.
The key part is: loadViewControllerAtIndex is used to switch the view controller. The following is the implementation:
-(Void) loadViewControllerAtIndex :( NSInteger) index {NSInteger nextIndex = 0; if (index = 0) {nextIndex = 1;} else if (index = 1) {nextIndex = 0;} UIViewController * fromViewController = _ viewControllers [nextIndex]; // obtain the current viewController UIViewController * toViewController = _ viewControllers [index]; // obtain the viewController to be switched
// If (self. childViewControllers. firstObject = toViewController) {return;} if (self. childViewControllers. count> 0) {self. view. userInteractionEnabled = NO; // disable the operation during the switchover. After the animation is switched over, [fromViewController willMoveToParentViewController: nil] will be restored; // fromViewController will remove [self addChildViewController: toViewController]; // Add toViewController to ContainerViewController
// Set the frame if (index = 1) {toViewController. view. frame = [self nextViewStartFrame];} else {toViewController. view. frame = [self preViewStartFrame];}
// The officially provided animation switching API, where the switching animation [self transitionFromViewController: fromViewController toViewController: toViewController duration: 0.25 options: UIViewAnimationOptionCurveEaseInOut animations: ^ {
// Execute the animation 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 ){
// After the animation is executed, add or remove the hierarchical link from the parent view 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 );
}
Use addChildViewController to add the ViewController to the ContainerViewController. To add a ViewController, follow these steps:
1. [self addChildViewController: toViewController]; add to current viewController
2. [self. view addSubView: toViewController. view]; add view to self. view
3. [toViewController didMoveToParentViewController: self]
There are several steps to remove a ViewController:
1. [fromViewController willMoveToParentViewController: nil]; nil indicates that the view will be removed
2. [fromViewController. view removeFromSuperView]; remove fromViewController. view from the parent view.
3. [fromViewController removeFromParentViewController]; remove fromViewController from the parent view level
It is necessary to add and remove ViewController. However, because transitionFromViewController: toViewController: duration: options: animations: completion: is used, it first adds toViewController. view is added to superView and then animated, so [self. view addSubView: toViewController. view]
After switching the function, we implement the button event function:
- (IBAction)buttonTouched:(id)sender { if (((UIButton *)sender).tag == 1) { [self loadViewControllerAtIndex:0]; } else { [self loadViewControllerAtIndex:1]; }}
Click different buttons to switch to different interfaces. The running effect is as follows:
Here we just roughly achieve the next switching effect, the new UIViewControllerContextTransitioning and UIViewControllerAnimatedTransitioning in iOS7 enhance the custom switching, this article has made a detailed description of the http://objccn.io/issue-12-3/
Reference: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html#//apple_ref/doc/uid/TP40007457-CH18-SW6