I am using this method:
[UIView transitionWithView: duration: options: animations: completion:];
to control a back animation on a segue. Precisely using this code:
[UIView transitionWithView:self.view.superview
duration:2.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self dismissModalViewControllerAnimated:NO];
}
completion:nil];
That works, but what I really want is not a Flip, it is a Push. In other words I want to see the views sliding from right to left, one replacing the other.
Unfortunately there is no UIViewAnimationOptionTransitionPushFromRight.
Therefore my question: how can I get the effect I want?
If you are using a navigationController, you can do something like this:
- (void)perform
{
UIViewController *source = (UIViewController*)[self sourceViewController];
UIViewController *destination = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.duration = .25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[source.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[source.navigationController pushViewController:destination animated:NO];
}
If you don't want to use a UINavigationController, and you want the source view controller to go away as opposed to using presentViewController, and you don't want the fade out animation caused by using kCATransitionPush, then the following solution will work. This also works if your views are transparent and you do not want the containing background to animate.
static UIImageView *screenShotOfView(UIView *view)
{
// Create a snapshot for animation
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImageView *screenShot = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
return screenShot;
}
- (void)perform
{
UIViewController *source = (UIViewController *) self.sourceViewController;
UIViewController *destination = (UIViewController *) self.destinationViewController;
// Swap the snapshot out for the source view controller
UIWindow *window = source.view.window;
UIImageView *screenShot = screenShotOfView(source.view);
CGRect originalFrame = destination.view.frame;
BOOL animsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
{
window.rootViewController = destination;
[window addSubview:screenShot];
[source.view removeFromSuperview];
CGRect frame = destination.view.frame;
frame.origin.x += source.view.bounds.size.width;
destination.view.frame = frame;
}
[UIView setAnimationsEnabled:animsEnabled];
[UIView animateWithDuration:kAnimationDuration
animations:^{
destination.view.frame = originalFrame;
CGRect frame = screenShot.frame;
frame.origin.x -= screenShot.bounds.size.width;
screenShot.frame = frame;
}
completion:^(BOOL finished) {
[screenShot removeFromSuperview];
}];
}
Related
May be this types of issue occurred with many developer, I also tried to find on Google but there is no luck to solve my problem.
In my app rootViewController set on window dynamically, I mean user can change root view at run time application. So first I am removing current rootViewController from UIWindow and then I set new rootViewController on UIWindow with specific animation.
This animation done by CATransition with transition.type = kCATransitionPush;.
My app working very well except animation of new rootViewController. As above I said that I used kCATransitionPush with CATransition
EDITED:
Below is my code:
-(void) changeRootViewController
{
for(UIView *subViews in self.window.rootViewController.view.subviews)
[subViews removeFromSuperview];
[self.window.rootViewController.view removeFromSuperview];
self.window.rootViewController.view = nil;
[self.window.rootViewController removeFromParentViewController];
MainRootViewController *mainRootVC = [[MainRootViewController alloc] init];
CATransition *animation = [CATransition animation];
[animation setDuration:0.4];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
animation.fillMode = kCAFillModeForwards;
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];
self.window.rootViewController = mainRootVC;
[[self.window layer] addAnimation:animation forKey:nil];
}
I also tried to set clearColor and whiteColor of background of UIWindow. But not working.
My Problem is : While animation is process (right to left) I am getting black shadow. So anybody can help me to hide this black shadow? Please give you golden suggestion.
Thanks.
Add in the delegate (didFinishLaunchingWithOptions method) these two lines :
self.window.backgroundColor = [UIColor whiteColor];
self.window.tintColor = [UIColor whiteColor];
I was having same requirement, I have 3 images of full screen size at splash screen which should slide from right to left. But used of CATransition doesn't solve the issue. So I have used scrollview with paging. Added 3 images in scrollview and then start animation.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
size = [UIScreen mainScreen].bounds.size;
imageArray = [[NSMutableArray alloc] init];
[imageArray addObject:[UIImage imageNamed:#"splashScreen1.png"]];
[imageArray addObject:[UIImage imageNamed:#"splashScreen2.png"]];
[imageArray addObject:[UIImage imageNamed:#"splashScreen3.png"]];
self.splashScrollView.frame = CGRectMake(0,0,size.width,size.height);
self.splashScrollView.contentSize = CGSizeMake(size.width * imageArray.count, size.height);
self.splashScrollView.pagingEnabled = YES;
CGFloat xPos = 0.0;
for (UIImage *image in imageArray) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(xPos, 0.0, size.width, size.height);
[self.splashScrollView addSubview:imageView];
xPos += size.width;
}
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(startAnimation) userInfo:nil repeats:NO];
}
This(startAnimation) method scrolled scrollView upto the width of image, on completion of first image animation, I have started second image animation which scrolled to the edge of scrollview width.
-(void) startAnimation{
[UIView animateWithDuration:2.0
animations:^{
self.splashScrollView.contentOffset = CGPointMake(size.width, 0.0);
} completion:^(BOOL finished) {
[UIView animateWithDuration:2.0
animations:^{
self.splashScrollView.contentOffset = CGPointMake((self.splashScrollView.contentSize.width - CGRectGetWidth(self.splashScrollView.frame)), 0.0);
} completion:^(BOOL finished) {
//At animation end go to login
}];
}];
}
I am new to iOS. I am trying to change the transition animation in navigation controller to load a new UIView controller from bottom to top, using Segue. I believe it will not be too hard to implement but may be I am not able to understand it.
I could not find any solution in other posts.
Here's the code I've been trying:-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"alarmSegue"]) {
tab2ViewController *destViewController = segue.destinationViewController;
UIView *destView = destViewController.view;
destViewController.selectionName = #"alarms";
[sender setEnabled:NO];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView animateWithDuration:0.0
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
[destView setTransform:CGAffineTransformMakeTranslation(0, -1000)];
//[destView setFrame:CGRectMake(0, 440, 400, 45)];
//destView.frame = CGRectMake(0, 0, 320, 460);
}
completion:^(BOOL finished){
[sender setEnabled:YES];
}];
[UIView commitAnimations];
}
}
I just want to implement a SIMPLE transition from bottom to top, using Segue. I want to set some properties of destination controller as well.
Replace the code between [UIView beginAnimations:nil context:nil]; and [UIView commitAnimations]; (including those two lines as well) with the following:
CGAffineTransform baseTransform = destView.transform; //1
destView.transform = CGAffineTransformTranslate(baseT,0,destView.bounds.size.height); //2
[UIView animateWithDuration: 0.5 animations:^{
destView.transform = baseTransform; //3
}];
Make a reference of the original transform.
Push our view down without an animation so we can animate it back up
Set the original transform back to the view. This time, it'll animate
You can further add the delay, options and completion parameters to that UIView Animation method. Xcode will probably help you with the autocompletes on those.
Well you are nearly there.
You need to change two things mainly:
1 Change the initial position of the view. You want the view to appear from bottom to top, so initially your view should be at the bottom. This piece of code should be written before the animation.
[destView setTransform:CGAffineTransformMakeTranslation(0, -1000)];
2 Then you need to slide from bottom to the original position , hence inside the animation block:
[destView setTransform:CGAffineTransformMakeTranslation(0, 0)];
One more suggestion, I guess you are using a newer version of iOS(above iOS4) instead of using animation blocks use UIView's animation method
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
For further info, refer description.
EDIT :
According to your edit on question, you are looking to change the transition animation for NavigationController in the app using storyboard. For that you could use Custom Segue. You will have to create a custom segue, a class that subclasses UIStorySegue and override its perform method like this:
-(void)perform {
//UIViewAnimationOptions options;
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.duration = 0.9f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[destinationController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:destinationController animated:NO completion:nil];
}
You have to change the segue class to this custom segue in storyboard as well, to make it function.
Try using transition effects
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"alarmSegue"]) {
CATransition transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = direction;
[self.view.layer addAnimation:transition forKey:kCATransition];
tab2ViewController *destViewController = segue.destinationViewController;
UIView *destView = destViewController.view;
destViewController.selectionName = #"alarms";
[sender setEnabled:NO];
}
}
I am hoping you can help me I am trying to implement a Custom Transition in my app that will display a Custom Modal View Controller. I am able to get the View Controller to appear as expected, however, I cannot get the transition to animate. Any help with this or pointers in the right direction would be greatly appreciated.
Please see my code below:
-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return 1.0;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect sourceRect = [transitionContext initialFrameForViewController:fromVC];
fromVC.view.frame = sourceRect;
UIGraphicsBeginImageContextWithOptions(fromVC.view.frame.size, NO, 0);
[fromVC.view drawViewHierarchyInRect:fromVC.view.bounds afterScreenUpdates:YES];
UIImage *fromVCImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIView *container = [transitionContext containerView];
[container setBackgroundColor:[UIColor colorWithPatternImage:fromVCImage]];
[container insertSubview:toVC.view belowSubview:fromVC.view];
CGRect fromVCFrame = fromVC.view.frame;
__block CGRect toVCFrame = toVC.view.frame;
toVCFrame.origin.y = fromVCFrame.origin.y + fromVCFrame.size.height;
[toVC.view setFrame:toVCFrame];
[toVC.view setAlpha:0.0];
[toVC.view setBackgroundColor:[UIColor colorWithPatternImage:fromVCImage]];
[transitionContext finalFrameForViewController:toVC];
//3.Perform the animation...............................
[UIView animateWithDuration:1.0
animations:^{
toVCFrame.origin.y = fromVCFrame.origin.y;
toVC.view.frame = toVCFrame;
[toVC.view setAlpha:1.0];
}
completion:^(BOOL finished) {
//When the animation is completed call completeTransition
[transitionContext completeTransition:YES];
}];
}
Adding Code from View Controller when presentViewController is called via a UITapGestureRecognizer
- (void) onTapGesture:(UITapGestureRecognizer *)recognizer
{
ImagesCollectionViewController *imagesCollectionView = [[Utils getStoryboardForDeviceWithIdentifier:MAIN_STORYBOARD] instantiateViewControllerWithIdentifier:IMAGES_VIEW];
imagesCollectionView.transitioningDelegate = self;
imagesCollectionView.modalTransitionStyle = UIModalPresentationCustom;
[self presentViewController:imagesCollectionView animated:YES completion:^{
}];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
return self.contentSlideTransitionManager;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
return self.contentSlideTransitionManager;
}
I'm going to guess that this is your problem:
[container insertSubview:toVC.view belowSubview:fromVC.view];
If toVC.view is below fromVC.view, it is hidden behind it, so you are not seeing what it does.
I'm trying to add a simple push animation between UIViewControllers using a custom segue.
(Without converting my controllers to use a UINavigationController)
The answers found so far work fine with a navigation controller, but fail when not using a navigation controller. (I am still reading and trying other answers I've seen here on stack-overflow)
My custom segue .m thanks to (ZHCustomSegue.m) Zakir on 7/5/12
#import "SFCustomSegue.h"
#import "QuartzCore/QuartzCore.h"
#implementation SFCustomSegue
-(void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.duration = 4.0;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[sourceViewController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:[self destinationViewController] animated:NO completion:nil];
}
If I use a navigation controller as per Zakir's original example and replace the last 2 lines with:
[sourceViewController.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[sourceViewController.navigationController pushViewController:destinationController animated:NO];
It works....
Apple's doc says (notice not a navigation controller, and using a modal segue):
- (void)perform
{
// Add your own animation code here.
[[self sourceViewController] presentModalViewController:[self destinationViewController] animated:NO];
}
By NOT Working, I get no animation. In Zakir's code, using 4.0 seconds it takes 4.0 seconds and I get the animation I want. Of course, if I use a navigation controller a push tranition is the default. In this code, I get no animation and it takes 0 seconds.
Has anyone gotten custom segue animations to work with UIViewControllers?
Since you are calling presentViewController, the source view controller is sticking around. If you actually want to replace the source view controller with the destination view controller, so that the source gets dealloced, you can do this:
static UIImageView *screenShotOfView(UIView *view)
{
// Create a snapshot for animation
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImageView *screenShot = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
return screenShot;
}
- (void)perform
{
UIViewController *source = (UIViewController *) self.sourceViewController;
UIViewController *destination = (UIViewController *) self.destinationViewController;
// Swap the snapshot out for the source view controller
UIWindow *window = source.view.window;
UIImageView *screenShot = screenShotOfView(source.view);
CGRect originalFrame = destination.view.frame;
BOOL animsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
{
window.rootViewController = destination;
[window addSubview:screenShot];
[source.view removeFromSuperview];
CGRect frame = destination.view.frame;
frame.origin.x += source.view.bounds.size.width;
destination.view.frame = frame;
}
[UIView setAnimationsEnabled:animsEnabled];
[UIView animateWithDuration:kAnimationDuration
animations:^{
destination.view.frame = originalFrame;
CGRect frame = screenShot.frame;
frame.origin.x -= screenShot.bounds.size.width;
screenShot.frame = frame;
}
completion:^(BOOL finished) {
[screenShot removeFromSuperview];
}];
}
It appears that my above code, is "nearly" working, but not quite.
The main issue at hand is likely when the final step is called.
My working code looks like this:
#import "SFCustomSegue.h"
#import "QuartzCore/QuartzCore.h"
#implementation SFCustomSegue
static const float delay = 0.5f;
-(void)perform {
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
[sourceViewController.view addSubview:destinationController.view];
CATransition* transition = [CATransition animation];
transition.duration = delay;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[sourceViewController.view.layer addAnimation:transition forKey:kCATransition];
[self performSelector:#selector(performDone:) withObject:destinationController afterDelay:delay];
}
- (void)performDone:(id)viewController{
UIViewController *destination = (UIViewController*)viewController;
[destination.view removeFromSuperview];
[[self sourceViewController] presentViewController:destination animated:NO completion:nil];
}
#end
The key to resolving this was adding the view for the transition (line 13), then removing it (line 28) and adding it back (line 29) using presentViewController:animated:completion:.
I am still "stuck" with using only the regular CATransition transition types, but that's good enough for me for now, since I want to use kCATransitionPush.
I have merged the ideas from both answers to get this code (working good):
(the answers from above don't count in the orientation of device so they won't work in landscape, for example)
(the variant with CATransitions wasn't appropriate because there was a gap between two views while the one pushed the another)
#import "PushSegue.h"
/*
#interface TransitionDelegate : NSObject
- (id) initWithScreenshot: (UIView*) screenshot;
#end
*/
#implementation PushSegue
- (void) perform
{
UIViewController* source = (UIViewController*) self.sourceViewController;
UIViewController* destination = (UIViewController*) self.destinationViewController;
const BOOL iPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
float animationDuration = iPad ? 0.5 : 0.3;
// Swap the snapshot out for the source view controller
UIWindow* window = source.view.window;
UIImageView* screenShot = screenShotOfView(source.view);
// accord to device orientation
float rotation;
//NSString* transitionType;
CGRect originalFrame = destination.view.frame;
CGRect destinationFrame = destination.view.frame;
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIInterfaceOrientationPortraitUpsideDown:
rotation = M_PI;
destinationFrame.origin.x -= source.view.bounds.size.width;
//transitionType = kCATransitionFromLeft;
break;
case UIInterfaceOrientationLandscapeLeft:
rotation = M_PI + M_PI_2;
destinationFrame.origin.y -= source.view.bounds.size.width;
//transitionType = kCATransitionFromBottom;
break;
case UIInterfaceOrientationLandscapeRight:
rotation = M_PI_2;
destinationFrame.origin.y += source.view.bounds.size.width;
//transitionType = kCATransitionFromTop;
break;
default:
rotation = 0;
destinationFrame.origin.x += source.view.bounds.size.width;
//transitionType = kCATransitionFromRight;
break;
}
screenShot.transform = CGAffineTransformMakeRotation(rotation);
// reposition after rotation
CGRect screenshotFrame = screenShot.frame;
screenshotFrame.origin.x = 0;
screenshotFrame.origin.y = 0;
screenShot.frame = screenshotFrame;
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIInterfaceOrientationPortraitUpsideDown:
screenshotFrame.origin.x += screenShot.bounds.size.width;
break;
case UIInterfaceOrientationLandscapeLeft:
screenshotFrame.origin.y += screenShot.bounds.size.width;
break;
case UIInterfaceOrientationLandscapeRight:
screenshotFrame.origin.y -= screenShot.bounds.size.width;
break;
default:
screenshotFrame.origin.x -= screenShot.bounds.size.width;
break;
}
// swap the view with its screenshot
window.rootViewController = destination;
[window addSubview:screenShot];
[source.view removeFromSuperview];
/*
CATransition* transition = [CATransition animation];
transition.duration = animationDuration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = transitionType;
transition.delegate = [[TransitionDelegate alloc] initWithScreenshot:screenShot];
[window addSubview:destination.view];
[screenShot.window.layer addAnimation:transition forKey:nil];
*/
const BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
{
destination.view.frame = destinationFrame;
}
[UIView setAnimationsEnabled:animationsEnabled];
[UIView animateWithDuration:animationDuration
animations:^
{
destination.view.frame = originalFrame;
screenShot.frame = screenshotFrame;
}
completion:^(BOOL finished)
{
[screenShot removeFromSuperview];
}];
/*
const BOOL animationsEnabled = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
{
CGRect frame = destination.view.frame;
frame.origin.x += source.view.bounds.size.width;
destination.view.frame = frame;
}
[UIView setAnimationsEnabled:animationsEnabled];
[UIView animateWithDuration:animationDuration
animations:^
{
destination.view.frame = originalFrame;
CGRect frame = screenShot.frame;
frame.origin.x -= screenShot.bounds.size.width;
screenShot.frame = frame;
}
completion:^(BOOL finished)
{
[screenShot removeFromSuperview];
}];
*/
/*
CATransition* transition = [CATransition animation];
transition.duration = animationDuration;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
switch ([UIApplication sharedApplication].statusBarOrientation)
{
case UIInterfaceOrientationPortraitUpsideDown:
transition.subtype = kCATransitionFromLeft;
break;
case UIInterfaceOrientationLandscapeLeft:
transition.subtype = kCATransitionFromBottom;
break;
case UIInterfaceOrientationLandscapeRight:
transition.subtype = kCATransitionFromTop;
break;
default:
transition.subtype = kCATransitionFromRight;
break;
}
[source.view.window.layer addAnimation:transition forKey:nil];
[source presentViewController:destination animated:NO completion:nil];
*/
}
static UIImageView* screenShotOfView(UIView* view)
{
// Create a snapshot for animation
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImageView* screenShot = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()];
UIGraphicsEndImageContext();
return screenShot;
}
#end
/*
#implementation TransitionDelegate
{
UIView* screenshot;
}
- (id) initWithScreenshot: (UIView*) screenshot
{
if (self = [super init])
{
self->screenshot = screenshot;
}
return self;
}
- (void) animationDidStop: (CAAnimation*) theAnimation
finished: (BOOL) flag
{
[screenshot removeFromSuperview];
}
#end
*/
In my app im showing different screen this way:
info = [[Info alloc]initWithNibName:#"Info" bundle:nil];
[self.view addSubview:info.view];
Info is a subclass of UIViewController, so i just create it and add it as a subview of the current view.
When i want to dismiss it i just do:
[self.view removeFromSuperview];
Im not sure if this is the right way of doing it, but yesterday apple has published on app store another app that do the same to display views.
My question is, how can i animate the transition between views, so when i call addsubview it do the animation?
I tried this:
info = [[Info alloc]initWithNibName:#"Info" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:info.view
cache:YES];
[self.view addSubview:info.view];
[UIView commitAnimations];
But its not working, this dont do anything.
It's not the right way to manage view hierarchy. You should use view controller methods for this (addChildViewController: & removeFromParentViewController). Then you can use method transitionFromViewController:toViewController:options:animations:completion: (or something like that) to do various animations.
to add a view controller's view use this
ChildViewController * child = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:info.view
cache:YES];
[self.view addSubview:child.view];
[UIView commitAnimations];
[self addChildViewController:child];
[child release];//for NON ARC
to remove view use this...
for (UIViewController *childVC in [self childViewControllers])
{
[childVC removeFromParentViewController];
}
[self.view removeFromSuperview];// YOU CAN ADD ANIMATIONS HERE
[self removeFromParentViewController];
HOPE this will help you, It is working fine for me....
You can use CATransition for that kind of animation without using navigationcontroller below is the code
Info *infoViewController = [[Info alloc]init];
CATransition *transition = [CATransition animation];
transition.duration = 0.50;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
UIView *containerView = self.view.window;
[containerView.layer addAnimation:transition forKey:nil];
[self presentModalViewController:infoViewController animated:NO];
Like this you can animate the view from left to right without using navigationcontroller.
You can give UIView Block Animation a shot. Something like this:
[UIView animateWithDuration:.25 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^
{
requiredView.frame = CGRectMake(0, 300.0, 400.0, 180.0);
} completion:^(BOOL finished)
{
}];
You can set the view's frame and position it outside the viewing co-ordinates and then change the frame accordingly to animate the UIView.