Hi
I have looked without success for the answer to this.
Am trying to flip views on iphone app. Rather than using the usual iOS3 methods I want to use block methods to animate the transition.
Can anyone suggest a snippet of code to help please?
I tried the animateWithDuration method suggested above, and it didn't work. I couldn't get it working until I used the following:
[UIView transitionFromView:viewOld
toView:viewNew
duration:.75
options:UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationCurveEaseIn
completion:^(BOOL finished)
{
// cleanup viewOld
}
];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
// Exchange the views here
[view1 removeFromSuperview];
[mySuperview addSubview:view2];
}
completion:NULL];
Related
I'm trying to animate a label embedded in a UIView.
this is the code :
-(void)displayText:(NSString*)text {
[label setText:text];
[UIView animateWithDuration:5.0
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[labelView setAlpha:1.0];
}
completion:nil
];
[UIView animateWithDuration:5.8
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[labelView setAlpha:0.0];
}
completion:nil
];
}
To verify, the method is called, i set a breakpoint.
The calls return immediatly but only the end of animations is displayed.
I wired the UIView to the controller.
Pls help, I'm stuck.
Thanks in advance !
Patrick
Correct,
When you animate views like this the animation doesn't actually happen on screen until the next pass of the runloop (i.e. once your method returns).
UIView will coalesce animations that are programmed sequentially.
Use the completion block to fade back out. The code looks a bit odd but it works great!
[UIView animateWithDuration:5.0
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[labelView setAlpha:1.0];
}
completion:^(BOOL completed){
[UIView animateWithDuration:5.8
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{[labelView setAlpha:0.0];}
completion:nil];
}];
In response to your comments:
The animations won't start until the next run of the runloop. They won't start until your app finishes what its doing. If you wait in the loop you will have the same problem and also freeze up your interface. Consider using individual labels for each letter, and add a progressively bigger delay for each animation. All these animation instructions will be queued up at once and then played out over the course of the next however many seconds. Imagine you are like a movie director, you tell each actor what to do in the next scene. Then, once everyone knows what to do you sit back and yell "action" and watch it all play out.
I have read apple documentation: http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/AnimatingViews/AnimatingViews.html#//apple_ref/doc/uid/TP40009503-CH6-SW1
For iOS3.0 and earlier, using this:
Method1:
[UIView beginAnimations:#"ShowHideView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
...
The new one, iOS4, can do this:
Method2:
[UIView animateWithDuration:1.0 animations:^{
firstView.alpha = 0.0;
secondView.alpha = 1.0;
}];
Q1. What I want to know is, in earlier method, they have this "ShowHideView" in beginAnimations, is that method a built-in one?
Q2. Are there any others built-in methods for animation in beginAnimations? If yes, where can I find all those methods?
Q3. And lastly, can I use those methods in latter method(method2) call?
You can get all the answers to your questions in the UIView Class Reference.
Q1: ShowHideView, as you have it, is not a method at all. It is simply an "application-supplied identifier for the animations". In reality, you don't need it. When I use this method, I just use NULL instead of supplying an identifier there.
Q2: You don't set animations in the beginAnimations:context: call. You even illustrate it there by calling setAnimationCurve. You can set the animations from this typedef.
Q3: Again, you don't declare animation types in animateWithDuration:animations: call either. Utilize setAnimationCurve: to do that in that example as well.
Blocks have the benefit of being able to nest the animations (in a queue almost) using the [UIView animateWithDuration:animations:completion:] selector. You can nest another call to this method inside the finished block like so:
[UIView animateWithDuration:1.0 animations:^{
// your first animations
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
// more animations
} completion:^(BOOL finished) {
// ... maybe even more
}]
}]
I abuse this in my code and find it much easier than using the beginAnimations/commitAnimations code. And, with iOS 5 approaching, the days of needing to support iOS 3.x are slipping away.
So I attempt to flip between two images, but the duration is seemingly ignored.
I understand that Apple has to do some animation very quickly to keep the magic alive, but is there a way to slow down the flipping?
My current object hierarchy is game board contains many cards which inherit from UIView.
A card has a face and back that are UIViews that host a UIImage and other data
[UIView animateWithDuration:15.0
animations:^(void) {
cardOne.center =CGPointMake(100, 100);
cardTwo.center =CGPointMake(100, 100);
//low level calls, to directly perform the image swap
[cardOne.face removeFromSuperview];
[cardOne addSubview:cardOne.back];
[cardOne sendSubviewToBack:cardOne.face];
//calling the transitionFromView to do the image swap
[UIView transitionFromView:cardOne.face
toView:cardOne.back
duration:10
options:UIViewAnimationTransitionFlipFromLeft
completion:^(BOOL finished){ }];
Thanks for your feedback. I attempted a mix of all you input and it did end up working correctly. I don't yet know why though.
Thanks for your responses. I tried reverting to the old style and it worked. I have not figured out why as yet.
The non-working code is commented out and the working code is left uncommented.
Thanks again
/*
[UIView animateWithDuration:animationDuration
animations:^{
[self.face removeFromSuperview];
[self addSubview:self.back];
[self sendSubviewToBack:self.face];
}];
*/
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kDefaultFlipSpeed];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self
cache:YES];
[self.face removeFromSuperview];
[self addSubview:self.back];
[self sendSubviewToBack: self.face];
[UIView commitAnimations];
I cant ask in a comment, so:
Have you tried with less than 10 seconds? More precisely between 0-1 second. Something like 0.5 seconds. Tell me if you notice any change in duration with these values.
My quick answer would be:
Try setting 10 seconds as 10.0 or 10.0f.
Hope it helps.
I have a subView that I want to toggle between hidden and not hidden by a button. How do I fade in the subview and fade it out? For now it just appears immediately and disappear immediately when I toggle the button.
I am wondering what is the easiest way to do this animation.
Thanks
On iOS 4.0+ Apple recommends you use their new, block-based animation methods. Using these, the code would look something like this:
[UIView animateWithDuration:2.0
animations:^{myView.alpha = 0.0;}];
The properties you are animating go inside the block (the ^{...} part). Blocks are sort of like functions, so you can put multiple lines of code inside of them, if you want to animate multiple properties. For example:
[UIView animateWithDuration:0.2
animations:^{
view.alpha = 0.0;
view.backgroundColor = [UIColor redColor];
}];
If you need to perform an action after the animation is complete, use the +animateWithDuration:animations:completion: method (which also uses blocks), for example:
[UIView animateWithDuration:0.2
animations:^{view.alpha = 0.0;}
completion:^(BOOL finished){ [view removeFromSuperview]; }];
For more info, check out the UIView Class Reference 'Animations' section and 'Animating Views with Blocks' section.
This is the old pre-4.0 way:
http://objcolumnist.com/2009/07/18/simple-uiview-based-animations-on-the-iphone/
... which has the advantage of being conceptually simple and easy to implement.
float alpha = 1.0; // or 0.0 if it's already visible and you want to fade out
[UIView beginAnimations:#"" context:NULL];
[UIView setAnimationDuration:2.0]; // seconds, not ms. guess how i know?
[mySubView setAlpha:alpha];
[UIView commitAnimations];
One simple question:
This is an example of an old fashion animation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[base setTransform:rotate];
[base setCenter:newCenter];
[UIView commitAnimations];
this can be written like
[UIView animateWithDuration:0.5 animations:^{
[base setTransform:rotate];
[base setCenter:newCenter];
}];
is there any advantage in rewriting the animation using this new form?
There should be some kind of gain, or Apple would not make this new function.
What do you guys say?
Apple made the change not for performance, but because blocks are an easier way to express this kind of thing. Previously you'd have to use selectors to be triggered when an animation finished, etc.
So - why to use animateWithDuration: because blocks save time, make code cleaner, and are just generally very useful.
And why to use beginAnimation: because you want to support versions of iOS prior to 4.0, where that code isn't available. Apple still need to provide both methods because they need to remain backwards compatible - but the documentation strongly recommends you use the blocks version of methods where available and appropriate.
I think animateWithDuration is newer and look better. I use it more than beginAnimation. It is more clear code. beginAnimation use when you need compatible for iOS version less than 4.0.
But in some case, beginAnimation has more advantage, make easier when you write a function with a parameter animated. Example:
- (void)moveSomethingWithAnimated:(BOOL)animated {
// Do other task 1
if( animated ) {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2];
someView.frame = newFrame;
otherView.frame = newFrame;
}
if( animated ) {
[UIView commitAnimations];
}
// Do other task 2
}
Instead of:
- (void)moveSomethingWithAnimated:(BOOL)animated {
// Do other task 1
if( animated ) {
[UIView animateWithDuration:0.2 animations:^{
someView.frame = newFrame;
otherView.frame = newFrame;
}];
}
else {
// duplicate code, or you have to write another function for these two line bellow
someView.frame = newFrame;
otherView.frame = newFrame;
}
// Do other task 2
}