I have a particular scenario that I'm trying to emulate and, being fairly new to Cocoa Touch, I'm not sure of the best way to accomplish it. Pardon my lacking tactical knowledge; hopefully some clear exposition will help.
What I'd Like To Emulate:
The app I'm looking at (in particular) is Beat. Below is an example of one of their UIViews - in particular, notice the gear icon for Settings at the bottom.
When that gear is touched or swiped up, two primary UIView changes occur:
- The original UIView is slid up the screen about 90% of the way (the key point being that it does not slide all the way up).
- A new UIView is slid up to fill that newly vacated 90% space.
This is the basic functionality that I would like to accomplish.
Implementation Idea #1: Single UIViewController w/ Multiple UIViews
At first, I considered having a single UIViewController manage both the "main" and the "settings" views. In that case, it would be a fairly simple thing to transition these views in the appropriate manner.
That said, this seems a bit cluttered to me. Depending on how robust my two sets of functionality are, that's a recipe to overload a single UIViewController. You might tell me that that's okay, but off the bat, it seems too much.
Implementation Idea #2: Multiple UIViewControllers Within Custom Container ViewController
This is the route I'm currently going down. It separates the two discrete sets of functionality into separate UIViewControllers (contained within a Container ViewController) and transitions between the two via:
- (void)flipFromViewController:(UIViewController *)fromController
toViewController:(UIViewController *)toController
{
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height;
fromController.view.frame = CGRectMake(0.0f, 0.0f, width, height);
toController.view.frame = CGRectMake(0.0f, height, width, height);
[self addChildViewController:toController];
[fromController willMoveToParentViewController:nil];
[self transitionFromViewController:fromController
toViewController:toController
duration:0.5f
options:UIViewAnimationOptionTransitionNone
animations:^(void) {
fromController.view.frame = CGRectMake(0.0f, -(height - 100.0f), width, height);
toController.view.frame = CGRectMake(0.0f, 100.0f, width, height);
}
completion:^(BOOL finished) {
[fromController removeFromParentViewController];
[toController didMoveToParentViewController:self];
}];
}
The problem with this is the transition: it doesn't seem to stop "90% of the way". It looks more like it's intended to completely transition out an "old" controller and in a "new" controller, even though my frame adjustments on the two UIViews are not supposed to be "complete" moves.
Where I'd Like Guidance
I'm not asking for a complete solution - your expertise would be too expensive. :) That said, being fairly new to this, I would love your insight on what the right approach would be. Please let me know if I can provide further information.
Thanks!
I do think your 2nd method is on the right track, and your intuition about using transitionFromViewController:ToViewController is also right -- I wouldn't use that method if you want both view controllers to be present and active. So, I would have the controller with the gear view be a child view controller of a custom container controller, then add the second child off screen to the bottom like you have. Then animate both views up using animateWithDuration:... At the end of that, animation, you should have what you want, and you container controller will have two children.