calling an animation? - iphone

I have placed the following code in my program
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionFade];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#"SwitchToView1"];
Everything works great but there is no animation when I build the project into the simulator.
Where and how do I call this animation? once I get this then I can submit it to the app store!

Do you have any views in your app or just a Window? I'm just wondering if you're adding the animation beneath everything else. In most of my apps and many of Apple's samples, there is an underlying MainWindow and all views are added up on top of that using ViewControllers or other controllers.
Also, have you thought about using the much simpler beginAnimation...commitAnimation?
If you're merely trying to animate the addition of a view and deletion of another, see my code for doing this with viewControllers:
- (void)switchTwoViews:(UIViewController *)view1 otherView:(UIViewController *)view2 cacheTheView:(BOOL) cache;
{
/*
This method is called when the info or Done button is pressed.
It flips the displayed view from the main view to the flipside view and vice-versa.
*/
UIViewController *coming = nil;
UIViewController *going = nil;
UIViewAnimationTransition transition;
[view1.view setUserInteractionEnabled: NO];
[view2.view setUserInteractionEnabled: NO];
if (view1.view.superview == nil) {
coming = view1;
going = view2;
transition = UIViewAnimationTransitionFlipFromLeft;
}
else {
coming = view2;
going = view1;
transition = UIViewAnimationTransitionFlipFromRight;
}
// [coming.view setFrame:CGRectMake(0, 0, 480, 320)];
NSArray *viewArray = [[NSArray alloc] initWithObjects:coming, going, nil];
[coming viewWillAppear:YES];
[going viewWillDisappear:YES];
[UIView beginAnimations:#"View Flip" context:viewArray]; {
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidEnd:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.view cache:cache];
[self.view addSubview: coming.view];
}
[UIView commitAnimations];
}
- (void) animationDidEnd:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
NSArray *viewArray = context;
[((UIViewController *)[viewArray objectAtIndex:1]).view removeFromSuperview];
[[viewArray objectAtIndex:1] viewDidDisappear:YES];
[[viewArray objectAtIndex:0] viewDidAppear:YES];
[[[viewArray objectAtIndex:0] view] setUserInteractionEnabled: YES];
[viewArray release];
}

Related

Transitions between UIView in the same UIViewController

I want to transit from UIView to another in the UIViewController when I press a button
I write this code:
- (IBAction)changeView:(id)sender {
CATransition* transition = [CATransition animation];
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
transition.duration = 1.0f;
transition.type = #"cube";
transition.subtype = #"fromTop";
[self.view1.layer removeAllAnimations];
[self.view1.layer addAnimation:transition forKey:kCATransition];
}
this code will transit the view1(UIview) to itself. how can I make it to transit to another UIView (e.g. view2). also where can I put the another UIview (view2) in the storyboard
Have you try like this?
self.view1.alpha = 0.0;
[UIView beginAnimations:#"flip" context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationDuration:1.0f];
self.view2.alpha = 1.0;
[UIView commitAnimations];
Have a look at this code snippet it's much more elegant. Also checkout Apple's documentation for more fancy UIViewAnimationOptions
- (IBAction)changeView:(id)sender
{
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
//Remove View-1 from the main view
[view1 removeFromSuperView];
//Add the new view to your current view
[self.view addSubView:view2];
} completion:^(BOOL finished) {
//Once animation is complete
}];
}
Ensure that the two views are a strong property of your view controller.
If you have two UIView for example take firstView and secondView and add it to UIViewController on same rect. and set hiddden property to secondView.
-(IBAction)flipFirstViewToSecondView{
secondView.hidden= NO;
[UIView transitionWithView:firstView duration:1.0f options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
[UIView transitionWithView:secondView duration:1.0f options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{
} completion:^(BOOL finished) {
secondView.hidden = NO;
firstView.hidden = YES;
}];
} completion:^(BOOL finished) {
}];
}
Thanks. just let me know if you have any problem to integrate it.

viewController no full screen

anyone know how to implement something like a viewController no full screen just like when we tap in search in the iPhone ?
I want that when the user make an swipe up a viewController (half height) be showed.
No segue !! I would like that the old view controller be showed at the same time.
Thanks in advance
I Add this type of functionality for whole project, i add the QRView in window so user swip up the view from any view of project...
See the Example of my code..
Just set the UISwipeGestureRecognizer to your second view which you want to present like bellow...
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionFade];
[animation setDuration:0.5];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut]];
[[self.view layer] addAnimation:animation forKey:kAnimationKey];
UISwipeGestureRecognizer *swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(addCustomBottomBar)] autorelease];
swipeGesture.numberOfTouchesRequired = 1;
swipeGesture.direction = (UISwipeGestureRecognizerDirectionDown);
[yourViewController.view addGestureRecognizer:swipeGesture];/// use your view name here, its depends on your requirement
UISwipeGestureRecognizer *swipeGestureTop = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(addCustomBottomBar)] autorelease];
swipeGestureTop.numberOfTouchesRequired = 1;
swipeGestureTop.direction = (UISwipeGestureRecognizerDirectionUp);
[yourViewController.view addGestureRecognizer:swipeGestureTop];
and this bellow method called when you swipe up view...
Also just add one BOOL variable with name isViewPop and set it to NO in your viewDidLoad: method ..
-(void)addCustomBottomBar{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.window cache:YES];
if (isqrcodepop) {
isViewPop=NO;
yourViewController.view.frame=CGRectMake(0, 430, 320, 70);
}
else{
isViewPop=YES;
yourViewController.view.frame=CGRectMake(0, 210, 320, 270);
[self.view bringSubviewToFront:yourViewController.view];
}
[UIView commitAnimations];
}
i hope this answer helpful for you...
If it is something simple I would add a UIView to your UIViewController just below the bottom-- then when you hit 'Search' or whatever, animate that UIView up in view with an animation block:
- (IBAction)btnTouch:(id)sender
{
[UIView animateWithDuration:0.3
delay:0.0
options: UIViewAnimationCurveEaseInOut
animations:^{
//bring searchView up
_searchView.transform = CGAffineTransformMakeTranslation(0, -80);
}
completion:^(BOOL finished){
}
];
}
Then when you are done, push the view back to its origin by using the same animation block with this line instead:
_searchView.transform = CGAffineTransformMakeTranslation(0, 0);
You could have the background view controller [self presentViewController:vc animated:YES completion:nil]; and set your front view controller's frame to half of the screen. This way, since bottom half of the front view is transparent, your background view controller will still be visible

How to implement UIView transition

I have an app which has a start screen with a start button on it. If you tap that button the view changes and a new view appears, let's call that main view.
The way I implemented it is one view controller per view. Now that I want to add transition animations this implementation causes problems. For example, I want to use the following code:
[UIView transitionFromView:startView toView: mainView duration: 2.0
options: UIViewAnimationOptionTransitionCurlDown completion: NULL];
But this doesn't do anything. Reading the documentation suggests that this only works if the view controller doesn't change. The documentation doesn't have any examples of a curl down transition where the view controllers change so I'm not sure what to do.
When I started writing the app I read the guidelines and they suggested that having one view controller per view is the correct way of doing what I'm doing.
Now what is the correct way to implement a view transition when the view controller changes too? Many thanks for your help!
Edit: I am looking for a solution where the first view controller is destroyed.
It was proposed that you effectively create a view controller, use its view, but then disregard the controller itself. This is not advised. In iOS you want to keep your view controller hierarchy synchronized with your view hierarchy. Any techniques like the one proposed are therefore problematic. (WWDC 2011 session 102, while on a different topic, view controller containment, has a lengthy discussion of the importance of keeping these two hierarchies synchronized.)
The most obvious problem is that certain events, notably rotation events, are not going to transmitted successfully to your new controller and you can get some very strange results. It's also not clear with your code above what happens with the old view that you removed, how you would transition back, how you'd clean up the now unnecessary game controller, what would happen on didReceiveMemoryWarning if you were in the game controller, etc. This just seems to introduce a ton a problems.
The easiest solution is apply standard pushViewController and/or presentViewController calls to go from one view to another, and just animate those transitions. If you have questions about either of those methods, or how to animate within the context of those methods, let me know.
By the way, the root of your question was how to transition between view controllers. Here is a old collection of transitions (some for push transitions, some for modal transition) that I was once playing around with. Maybe there's something here that you could use?
- (void)transitionToNewController
{
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"MyView" bundle:nil];
#if TRANSITIONTYPE == 1
// pushViewController with push/slide from right via CATransition
CATransition* transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromRight;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:controller animated:NO];
#endif
#if TRANSITIONTYPE == 2
// pushViewController with flip using UIView begin/commitAnimations
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:controller animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
#endif
#if TRANSITIONTYPE == 3
// pushViewController with flip using animation block
[UIView animateWithDuration:0.5
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.navigationController pushViewController:controller animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}
completion:nil];
#endif
#if TRANSITIONTYPE == 4
// pushViewController with fade via CATransition
CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.type = kCATransitionFade;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:controller animated:NO];
#endif
#if TRANSITIONTYPE == 5
// pushViewController with fade via animation block
controller.view.alpha = 0.0f;
[UIView animateWithDuration:0.5
animations:^{
self.view.alpha = 0.0f;
controller.view.alpha = 1.0f;
}
completion:^(BOOL finished){
[self.navigationController pushViewController:controller animated:NO];
self.view.alpha = 1.0f; // reset the src alpha so it's there when you pop your view controller off
}];
#endif
#if TRANSITIONTYPE == 6
// pushViewController Flip using UIView begin/commitAnimations
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:controller animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self.self navigationController].view cache:NO];
[UIView commitAnimations];
#endif
#if TRANSITIONTYPE == 7
// pushViewController animation using CGAffine scale to look like we're zooming into the new view
[self.view addSubview:controller.view];
[controller.view setFrame:self.view.window.frame];
[controller.view setTransform:CGAffineTransformMakeScale(0.5,0.5)];
[controller.view setAlpha:1.0];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationCurveEaseOut
animations:^{
[controller.view setTransform:CGAffineTransformMakeScale(1.0,1.0)];
[controller.view setAlpha:1.0];
}
completion:^(BOOL finished){
[controller.view removeFromSuperview];
[self.navigationController pushViewController:controller animated:NO];
}];
#endif
#if TRANSITIONTYPE == 8
// presentViewController animation with slide from right by using CGAffineTransform
self.view.transform = CGAffineTransformMakeTranslation(0, 0);
controller.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
[self.view addSubview:controller.view];
[UIView animateWithDuration:4.0
animations:^{
// [self presentViewController:controller animated:NO completion:nil];
self.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
controller.view.transform = CGAffineTransformMakeTranslation(0, 0);
}
completion:^(BOOL finished){
[controller.view removeFromSuperview];
[self presentViewController:controller animated:NO completion:nil];
}
];
#endif
#if TRANSITIONTYPE == 9
// presentViewController animation with slide from right by just animating frames
float width = self.navigationController.view.frame.size.width;
CGPoint right = controller.view.center;
right.x += width;
controller.view.center = right;
[self.navigationController.view addSubview:controller.view];
[UIView animateWithDuration:0.5
animations:^{
CGPoint left = self.navigationController.view.center;
left.x -= width;
self.navigationController.view.center = left;
}
completion:^(BOOL finished){
[controller.view removeFromSuperview];
[self presentViewController:controller animated:NO completion:nil];
}
];
#endif
#if TRANSITIONTYPE == 10
// presentViewController animation with flipfromright
[UIView animateWithDuration:4.0
delay:0.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[self.view addSubview:controller.view];
}
completion:^(BOOL finished){
[controller.view removeFromSuperview];
[self presentViewController:controller animated:NO completion:nil];
}];
#endif
#if TRANSITIONTYPE == 11
// presentViewController with flip using UIView begin/commitAnimations
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self presentViewController:controller animated:NO completion:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
[UIView commitAnimations];
#endif
#if TRANSITIONTYPE == 13
// pushViewController with flip using animation block with transitionWithView
controller.view.frame = self.view.window.frame;
[UIView transitionWithView:self.view.superview
duration:1.0
options:UIViewAnimationTransitionFlipFromRight
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.view.superview addSubview:controller.view];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}
completion:^(BOOL finished){
[self.navigationController pushViewController:controller
animated:NO];
}];
#endif
}
Okey-doke, I found a neat way to achieve exactly what I want. This code, added in the method where I exchange the old view controller and view with the new one, works great:
GameViewController *game = [[GameViewController alloc] init];
UIView *currentView = [currentViewController view];
// remove the current view and replace with myView1
[currentView removeFromSuperview];
// set up an animation for the transition between the views
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromBottom];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[window layer] addAnimation:animation forKey:#"SwitchToView1"];
[self setCurrentViewController: game];
[window addSubview:[currentViewController view]];
[game release];
Many thanks to HERE!!

Why are my CATransitions acting up?

I am using the following code to switch between views with CATransition.
CATransition *applicationLoadViewIn = [CATransition animation];
[applicationLoadViewIn setDuration:20];
[applicationLoadViewIn setType:kCATransitionPush];
[applicationLoadViewIn setSubtype:kCATransitionFromTop];
[applicationLoadViewIn setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
ViewToSwitchTo *myviewcontroller = [[ViewToSwitchTo alloc] init];
[self.view.layer addAnimation:applicationLoadViewIn forKey:kCATransitionPush];
[self.view addSubview:myviewcontroller.view];
It functions mostly how I want it to. It pushes from the top like it should, however it for some reason acts strangely. First, the view I am switching to starts coming in from the bottom like it should, but for some reason, the view that I am switching FROM appears over the top of it with low opacity, so you see both of them. However, you also see the view that is coming in, shifted maybe 100 pixels upwards, on top of itself and the other view, once again with low opacity. Just before the halfway point of the the transition, everything works fine, you only see the view that is coming in and the view going out, doing what they should be doing. But slightly after the halfway point, the view I am switching to appears in its final destination, under the view I am switching from, and the view I am switching from has been reduced in opacity.
What is going on here?
I really not understand what you want but hope this code will help to implement ,if not then tell more about you CATransition
-(void) startAnimation {
fullImageView.alpha = 0.50;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:NO];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(pulseAnimationDidStop:finished:context:)];
fullImageView.alpha = 1.0;
[UIView commitAnimations];
}
- (void)pulseAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
if(hasFocus) {
[self startAnimation];
} else {
fullImageView.alpha = 1.0;
}
}
-(void) setHasFocus:(BOOL)_hasFocus {
hasFocus = _hasFocus;
if(hasFocus) {
[self startAnimation];
}
}
You can use this way as well
CATransition *applicationLoadViewIn = [CATransition animation];
[applicationLoadViewIn setDuration:1.5];
[applicationLoadViewIn setType:kCATransitionPush];
[applicationLoadViewIn setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
//[applicationLoadViewIn setRepeatCount:114];
productVC=[[PoductViewController alloc]initWithNibName:#"PoductViewController" bundle:[NSBundle mainBundle]];
[[productVC.view layer] addAnimation:applicationLoadViewIn forKey:kCATransitionPush];
[self.view addSubview:productVC.view];
But I suggest you to use Navigation Controller in place of
[self.view addSubview:productVC.view];
just use
[self.navigationController pushViewController:productVC animated:YES];
If you use this, there will be no background view, you will see white screen of the present view. But if you add subview, then you need to manually remove subview.

Hitting buttons while UIView is in transition, flipping in or out

My son just discovered that he could hit my view's "Done" button, which flips to the previous view, once to start the flip and one or more times as the view is in transition (flipping out). The second and next hits would trigger the same action over again, creating some interesting results, such as ending up with no views visible, but my underlying UIWindow.
I am thinking that I should call:
[coming.view setUserInteractionEnabled: NO];
[going.view setUserInteractionEnabled: NO];
on both the views involved in the flip transition, and then
[coming.view setUserInteractionEnabled: YES];
on the final view after animation has ended.
I was thinking that maybe better than this would be some way to globally disable taps while any view was in transition. What do you think?
Here is the entire view switching code:
- (void)switchTwoViews:(UIViewController *)view1 otherView:(UIViewController *)view2
{
/*
This method is called to switch views.
It flips the displayed view from the main view to the flipside view and vice-versa.
*/
UIViewController *coming = nil;
UIViewController *going = nil;
UIViewAnimationTransition transition;
[view1.view setUserInteractionEnabled: NO];
[view2.view setUserInteractionEnabled: NO];
if (view1.view.superview == nil) {
coming = view1;
going = view2;
transition = UIViewAnimationTransitionFlipFromLeft;
}
else {
coming = view2;
going = view1;
transition = UIViewAnimationTransitionFlipFromRight;
}
// coming.view.frame = [UIScreen mainScreen].applicationFrame;
// going.view.alpha = 1.0; //uncomment these lines if we want fading of views
// coming.view.alpha = 0.0;
NSArray *viewArray = [[NSArray alloc] initWithObjects:coming, going, nil];
[coming viewWillAppear:YES];
[going viewWillDisappear:YES];
[UIView beginAnimations:#"View Flip" context:viewArray]; {
[UIView setAnimationDuration:1.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidEnd:finished:context:)];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
// coming.view.alpha = 1.0; //uncomment these lines if we want fading of views
// going.view.alpha = 0.0;
[UIView setAnimationTransition:transition forView:self.view cache:YES];
[self.view addSubview: coming.view];
}
[UIView commitAnimations];
}
- (void) animationDidEnd:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
NSArray *viewArray = context;
[((UIViewController *)[viewArray objectAtIndex:1]).view removeFromSuperview];
[[viewArray objectAtIndex:1] viewDidDisappear:YES];
[[viewArray objectAtIndex:0] viewDidAppear:YES];
[[[viewArray objectAtIndex:0] view] setUserInteractionEnabled: YES];
[viewArray release];
}
setUserInteractionEnabled: seems to be the way to go. Any objections?