PDA

View Full Version : animating view switch




liptonlover
Nov 4, 2008, 02:33 PM
I have a window, and a list of views who are all sub views of the window. Right now, I simply do the following to switch to a new view.
[window bringSubviewToFront:aView];
Now I want to animate switching views, by sliding the new one down into the window frame. How should I do this? It looks like the "Animating Views" block of methods in UIView is what I need to do, but to be honest I don't understand how to use them. Or should I just use a timer or even a simple C loop? Any help would be appreciated.
Thanks, Nate



jnic
Nov 5, 2008, 07:37 AM
I want to animate switching views, by sliding the new one down into the window frame.


// Move your sub-view off the screen.
CGRect rect = viewToAnimate.frame;
CGPoint origin = CGPointMake(0, -480);
rect.origin = origin;
viewToAnimate.frame = rect;

// Use a transform to slide it on.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
viewToAnimate.transform = CGAffineTransformMakeTranslation(0, 480);
[UIView commitAnimations];


Apple provide plenty of sample code for view transitions: http://developer.apple.com/iphone/library/samplecode/ViewTransitions/index.html

liptonlover
Nov 5, 2008, 10:09 AM
Thank you... it works great except for one thing. I can only switch twice. One to go to the second view, and one to go back. After that, pressing the switch button doesn't work. I have two views, each one has a button on it. When I press the button showing up, it's supposed to go to the other view. So all I have is a window, two views, two buttons, and an appcontroller.
I haven't really looked into what all the code means, but do I possibly need to somehow release the animation once it's done, even though I'm dealing with class methods? Or maybe I need a delegate so that I know when the animation is done?
Nate

jnic
Nov 5, 2008, 10:54 AM
This is the key line:

viewToAnimate.transform = CGAffineTransformMakeTranslation(0, 480);


Each time you call that transform, it shifts the view down 480 pixels in the y-axis.

liptonlover
Nov 5, 2008, 11:06 AM
But every time the button is pressed, I'm shifting the view up 480 before placing it on top of the view stack and animating it down. So unless that code isn't getting called the second time for some reason, which it should since it's in the IBAction method, it should work.
Nate

liptonlover
Nov 5, 2008, 05:17 PM
Ok I have more information, but still no answer. I modified numbers and sizes so that the same thing happens, but on a small scale in the window. The buttons are in the window, not the view so I have access to them the whole time. The views are much smaller, so I can see where they go when I press the button. I press go to view two, and view two jumps just above the other view, then slides down into place on top of the other. I press go to view one, and the same happens with view one. I press go to view two again, and it jumps up but doesn't slide back down. I press it again and it stays there. Same with go to view one. So my diagnosis is that the animation block is only being run once, total for each button. For some reason that code, which is just more code in the button methods, isn't getting run through. The other code, however, which is all before the animation of course, is getting called.

Analyzing what you said more carefully, I still don't understand how I fix it. But I think I might understand what you're saying. does setTransform:...(0,480) send the view to that location, or move it that far? Either way it should work every time as far as I can tell, but I don't know.

What I'm really curious about is why it only works once. If there's something wrong with the location stuff and all that it should mess up the first time as well, right?

:confused::confused::confused::confused::confused::confused:,
Nate

CommanderData
Nov 5, 2008, 07:03 PM
Ok I have more information, but still no answer. I modified numbers and sizes so that the same thing happens, but on a small scale in the window. The buttons are in the window, not the view so I have access to them the whole time. The views are much smaller, so I can see where they go when I press the button. I press go to view two, and view two jumps just above the other view, then slides down into place on top of the other. I press go to view one, and the same happens with view one. I press go to view two again, and it jumps up but doesn't slide back down. I press it again and it stays there. Same with go to view one. So my diagnosis is that the animation block is only being run once, total for each button. For some reason that code, which is just more code in the button methods, isn't getting run through. The other code, however, which is all before the animation of course, is getting called.

Analyzing what you said more carefully, I still don't understand how I fix it. But I think I might understand what you're saying. does setTransform:...(0,480) send the view to that location, or move it that far? Either way it should work every time as far as I can tell, but I don't know.

What I'm really curious about is why it only works once. If there's something wrong with the location stuff and all that it should mess up the first time as well, right?

:confused::confused::confused::confused::confused::confused:,
Nate

I may be completely off base, but think the problem is your Transform remains in effect on the view. When you start the first time through there is *no* Transform applied. You start up out of sight, and use the Transform to move down 480 pixels. Next time through, you move the view up 480 pixels by changing the origin, but the Transform is still in effect (it was not removed or reversed).

Maybe you should set viewToAnimate.transform = CGAffineTransformMakeTranslation(0, 0); before setting the origin?

jnic
Nov 6, 2008, 04:14 AM
CommanderData is exactly right; the transform is relative to the initial coordinates of the frame, so to return the view to the origin we defined earlier, you do:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
viewToAnimate.transform = CGAffineTransformMakeTranslation(0, 0);
[UIView commitAnimations];

Docs here: http://developer.apple.com/documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html

liptonlover
Nov 6, 2008, 07:16 AM
It works, and thanks for the doc, I'll read it.
Thank you thank you thank you thank you thank you!
Nate