一种选择是使用UISplitViewController
which 为您完成大部分工作。但这是我将如何去做。
有一个 HomeViewController,它是控制的基础层。这个类将处理:
1.1 左侧按钮的 UI
1.2 控制按下左键时发生的情况
1.3 切换右侧的子视图控制器
左边UIView
有个叫navView什么的,右边UIView
有个叫containerView。
2.1 navView 将始终可见
2.2 containerView 负责显示你childViewController
的视图
每当按下左侧的按钮时,您都会删除当前的 childViewController 并添加一个新的。
这是一个很好的教程
编辑**
回应评论:
When you initialize the TabBar it keeps an array of the viewControllers. So your right, viewDidLoad is only called once. All you have to do to achieve that is keep an array of all your viewControllers and switch them from there. I can post code on this if you want, it seemed a bit overkill for the initial question
这是我如何做到的示例:
- (void)updateChildViewController {
//This is the VC that was being shown, but will be replaced by the new currentlyVisisbleViewController, we keep track of it so in the transitionFromViewController: method we have viewController to switch from.
UIViewController *previousVisibleViewController = self.currentlyVisibleViewController;
//We keep and array of both view controllers so that we only have to load them into memory once, so their viewDidLoad is only called once.
if (!viewControllers) {
viewControllers = [[NSMutableArray alloc] initWithObjects:[NSNull null], [NSNull null], nil];
}
//If a given VC has not been loaded before we know becuase it's spot in the viewControllers array will be Null. (as seen in the line above)
if ([viewControllers objectAtIndex:self.displayType] == [NSNull null]) {
id newlyLoadedViewController;
//I have two display types I switch between, a map and list
if (self.displayType == DTMap) {
newlyLoadedViewController = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
}
else if (self.displayType == DTList) {
newlyLoadedViewController = [[ListViewController alloc] initWithNibName:@"ListViewController" bundle:nil];
}
//Set the object in it's location in viewControllers array
[viewControllers setObject:newlyLoadedViewController atIndexedSubscript:self.displayType];
}
//Set the new currentlyVisibleViewController
self.currentlyVisibleViewController = [viewControllers objectAtIndex:self.displayType];
//Adjust the frame to fit in the contentView (or the "container" view)
self.currentlyVisibleViewController.view.frame = self.contentView.frame;
//Make sure that it resizes on rotation automatically along with the contentView.
self.currentlyVisibleViewController.view.autoresizingMask = self.contentView.autoresizingMask;
//Let the old VC know that is going to be removed if it exist. We lazy load the UIViewControllers so on intial launch, there is only one UIViewController loaded, once we switch to another one we will have a previousVisibleViewController.
if (previousVisibleViewController) {
[previousVisibleViewController willMoveToParentViewController:nil];
}
//Add the currentlyVisibleViewController as a childViewController
[self addChildViewController:self.currentlyVisibleViewController];
//If there was a previousVC then we animate between them
if (previousVisibleViewController) {
[self transitionFromViewController:previousVisibleViewController
toViewController:self.currentlyVisibleViewController
duration:0.0f
options:UIViewAnimationOptionTransitionNone
animations:^{}
completion:^(BOOL finished) {
//Notify the new visible viewController than the move is done
[self.currentlyVisibleViewController didMoveToParentViewController:self];
//Tell the old one it is no longer on the screen and has been removed.
[previousVisibleViewController removeFromParentViewController];
}];
}
//Otherwise it's the first time we are adding a child so we need to link the views
else {
//Add it to content view, calls willMoveToParentViewController for us. We only have to set this once.
[self.contentView addSubview:self.currentlyVisibleViewController.view];
}
}