Present UIViewController from Side
I'm trying to present a UIViewController from the side. The only thing that Present 开发者_开发百科Modal can do is Verticle Slide in.
Any body have any ideas about this?
Let me know' thanks
To be anal about the MVC, its really the View your moving and not the controller.
I would recommended the way of doing this would be to use a navigation controller, it's animation is a horizontal slide by default and you get a navigation stack for free- this means that you have back buttons auto generated and, title and button properties that you can set, although these can be hidden easily is desired.
Using a navigation controller:
create a UINavigationsController property in your parent controller, syth, alloc and init it appropriately. Then you can load the controllers in in any order you want and it looks after the navigation.
Here is a good tutorial on NavControllers (usually they are used with UITableViewControllers but don't have to be)
Peng's example is an animation and I should note that it removes the parent view (and depending on your design might not just remove the 'currentView' - as your/a top view might be a subView) so if your navigating back you would have to handle this yourself.
I did this and it worked, though I don't know if there is a more official way to do it (UIVIewAimationTransition doesn't have a slide option):
UIView *currentView = self.view;
UIView *theWindow = [currentView superview];
[currentView removeFromSuperview];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:@"SwitchToView1"];
I just gave this answer to another SO question that was very similar, but here it is again, in case folks looking end-up here, instead.
All of the ViewControllers in my app inherit from MyViewController
which, in addition to some other default behaviours, has this property:
@property(readwrite, nonatomic) BOOL slideFromSide;
And this code:
- (void) presentViewController: (UIViewController*) vc animated: (BOOL) flag completion: (void (^)(void)) completion
{
BOOL slideIn = NO;
if ([vc isKindOfClass: [MyViewController class]])
{
MyViewController *svc = (MyViewController*) vc;
slideIn = svc.slideFromSide;
}
if (slideIn)
{
[self addChildViewController: vc];
[self.view addSubview: vc.view];
CGRect frame = vc.view.frame;
frame.origin.x = frame.size.width;
vc.view.frame = frame;
frame.origin.x = 0;
[UIView animateWithDuration: 0.33
animations: ^{
vc.view.frame = frame;
}
];
}
else
{
[super presentViewController: vc animated: flag completion: completion];
}
}
- (IBAction) backAction: (id) sender
{
if (_slideFromSide)
{
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width;
[UIView animateWithDuration: 0.33
animations: ^{
self.view.frame = frame;
}
completion:^(BOOL finished) {
[self removeFromParentViewController];
}
];
}
else
{
[self dismissViewControllerAnimated: YES completion: nil];
}
}
Then, in the ViewControllers where I want to slide-in, I have:
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName: nibNameOrNil bundle: nibBundleOrNil];
if (self)
{
self.slideFromSide = YES;
// Whatever else you want to do
}
return self;
}
Calling a new ViewController is just like normal:
WhateverViewController *vc = [WhateverViewController alloc] initWithNibName: nil bundle: nil];
[self presentViewController: vc animated: YES completion: nil];
精彩评论