iPhone: transitioning views with Core Animation - iphone

On the Mac, the best way for a simple cross-fade transition of views (without any custom keyframe timing) is to do something such as the following excerpt:
[[self animator] replaceSubview:aView with:bView];
Unfortunately the animator property isn't available on the iPhone. What's the best bet of doing this on the iPhone? Is it setting alpha channels on each view? Sample code would be excellent.
Thanks.

The basic way to animate views on the iphone is to use the UIView beginAnimations and commitAnimations calls. They allow you to modify the animatable properties of a view and have those changes animated.
For instance I have a custom view that is hidden and shown using this approach:
- (void) showAView:(CustomAView *)aView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
aView.frame = CGRectMake(0.0f, 110.0f , aView.frame.size.width, aView.frame.size.height);
[UIView commitAnimations];
}
- (void) hideAView:(CustomAView *)aView
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
aView.frame = CGRectMake(0.0f, self.view.frame.size.height, aView.frame.size.width, aView.frame.size.height);
[UIView commitAnimations];
}
By wrapping the frame property change in the UIView beginAnimations/commitAnimations the change has a standard animation applied to it.
You can add additional properties to the animation by using UIView animation class methods eg.
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

Related

UIView animation is leaking

In my viewcontroller i am using animation for changing the frame of UIButton and UIView, going from portrait to landscape user can see views growing but problem is animation is leaking everywhere and showing everything coming from different sides.
Here is the code
[UIView beginAnimations:Nil context:Nil];
[UIView setanimationDuration:1];
[view1 setFrame:CGRectMake(100,100,200,300)];
[UIView commitAnimations];
Thanks
Please elaborate more on what "leaking everywhere" means, and does it make a difference if you use block animation:
[UIView animateWithDuration:1.0 delay:0.0 options:nil animations:^{
[view1 setFrame:CGRectMake(100,100,200,300)];
}completion:^(BOOL done){
if (done) {
NSLog(#"animation complete");
}
}];
According to Apple's documentation:
In iOS 4 and later, use the block-based animation methods.
(Recommended)

orientation change

I need to show fade-in kind of transition effects while the view changes its orientation from one mode to other. Can anyone suggest me how to get that?
I would use an animation block inside of this method like so:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[UIView beginAnimations:#"InterfaceFade" context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:duration];
// Change properties to animate here (Ex: view.alpha = 0.0)
[UIView commitAnimations];
}

how to implement an iPhone view transition animation with both flipping and scaling?

how can I implement the animation we see in the iPhone Music app's coverflow screen? when you click on a small view, it flips and scales up to another view? how can I do this? I can use core animation to flip and scale a view, but how can I do the transition to another view? thanks
You need an UIView as Container for the two UIViews (frontside/backside) and then remove/add these from/to the container as subviews while doing the animations in between:
UIView *flipContainer;
UIView *frontSide;
UIView *backSide;
//...
-(void)turnUp
{
[backSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1.2, 1.2);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:frontSide];
}
-(void)turnDown
{
[frontSide removeFromSuperview];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:flipContainer cache:YES];
[UIView setAnimationDuration:1.0];
CGAffineTransform transform = CGAffineTransformMakeScale(1, 1);
flipContainer.transform = transform;
[UIView commitAnimations];
[flipContainer addSubview:backSide];
}
I'm trying the exact code you are doing - I get a zoom effect but no turn over. The only difference is that right before the turnUp code I add the flipContainer (with back showing) so then it can be flipped over.
// construct animation container
self.flipContainer = [[FlipContainer alloc] init];
[self.flipContainer.view setFrame:CGRectMake(clickedSquareX, clickedSquareY, 200, 200)];
[self.flipContainer.view addSubview:self.backside.view];
// add animation container
[self.myParentView.view addSubview:self.flipContainer.view];
// PROCEED to your turnUp code
The reason I'm doing this is I have a bunch of images in a horizontal UIScrollView and so to 'simulate' a 200x200 image flipping over and zooming to show detail I add my flipContainer with the backside showing the exact image over the exact spot of the pressed image. It should work shouldn't it? A bit confusing to me is the first line of your turnUp code you do:
[backSide removeFromSuperview];
..which would remove the view I just added.
I'm not sure if this is the right spot to put this question in - sorry if it isn't!

UIScrollView scrollRectToVisible at custom speed

I have a UIScrollView and I'm calling scrollRectToVisible:animated:YES on it.
I would like to set the speed at which it is animated. Can that be done?
I ended up finding a solution. In my case, the scrolling was animated programmatically after launch, to mimic a slot machine (with 3 horizontal UIScrollViews). Was doing this with the scrollRectToVisible:animated: method.
I got to set a custom speed using UIView's beginAnimation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:(abs(rMid-pMid)*0.3)];
scrollMid.contentOffset = CGPointMake(rMid*320, 0);
[UIView commitAnimations];
AnimationDuration depends on the distance the scroller has to move between each "drawing".
A modern version with blocks:
[UIView animateWithDuration:1.0 animations:^{
[self.scrollView scrollRectToVisible:CGRectMake(...) animated:NO];
} completion:^(BOOL finished) {
...
}];

adding a category for UIView animations

I would like to have a category for UIViewController containing few simple methods to move the view controller's view around, fading it etc...
For example the method below fades in/out a the VC's view.
I'm not using instance variables and the onTransitionIn: method is called, the problem is the view doesn't fade in/out.
Can someone tell me what I'm doing wrong?
Thank you!
EXAMPLE:
#implementation UIViewController (UIViewControllerAdditions)
- (void)onTransitionIn:(BOOL)isIn {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:ANIM_DUR];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
int newAlpha = 1;
if (!isIn) {
newAlpha = 0;
[UIView setAnimationDidStopSelector:#selector(hideAnimationDidStop)];
}
// set the new alpha
self.view.alpha = newAlpha;
[UIView commitAnimations];
}
Try adding this:
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromRight forView: self.view cache:YES];
after the line:
[UIView setAnimationDelegate:self];
Also take a look at these:
iPhone UIView Animation Best Practice
How to animate View swap on simple View iPhone App?