I have this code:
when image change alpha from 0.00 to 1.00 it is imediately and not in 3 seconds, why?
- (void) startAnimation{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];
[successView setAlpha:1.00];
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];
[successView setAlpha:0.00];
[UIView commitAnimations];}
Both animations are run in the same run cycle (that's how UIView animations work—all animations in one run cycle are "concatenated." You'll need to use
[UIView setAnimationDelay:3.0];
On the second animation.
Example Code
There are two ways to do this—using the standard begin/commit animations, or using the blocks method. This example uses the begin/commit animations code, which is what you have. The issue is because the animations are being concatenated, and without going into CA, the standard animation behavior is for one to be "forced" to end before the other runs. It has to do with run loops; Building Animation-Driven Interfaces from WWDC 2010 goes into depth about this. But the code to do what you want looks like this:
- (void)fadeOut {
[UIView beginAnimations:#"Animation2" context:NULL];
[UIView setAnimationDuration:3];
[self.testView setAlpha:0.00];
[UIView commitAnimations];
}
- (IBAction)animate {
[UIView beginAnimations:#"Animation1" context:NULL];
[UIView setAnimationDuration:3];
[self.testView setAlpha:1.00];
[UIView commitAnimations];
[self performSelector:#selector(fadeOut) withObject:nil afterDelay:3.0];
}
You have to force it to break up the run loop, basically. The key thing to remember is that animations are not executed sequentially, as you might expect code to be.
The blocks-based code looks like this. Note that I'm using the autorepeat option, which automatically repeats the animation. Note though that in the animation, you are setting a property, so by default after the animation completes the view will go back to being visible. Therefore, you have the set the property again to zero in the completion block.
- (IBAction)animate {
[UIView transitionWithView:self.testView duration:3.0 options:UIViewAnimationOptionAutoreverse animations:^{self.testView.alpha = 1.0;} completion:^(BOOL finished) {self.testView.alpha = 0.0;}];
}
Hopefully this helps!
Related
I have a animation view. When the animation is finished I would like to show a new view by setting its hidden to false.
I set the hidden to false after the animation block code, but it seems like the animation is being done on a separate thread. The view gets unhidden while the animation block is still playing
// start animation block
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut ];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:mCards[r] cache:YES];
// mCards[0].image = [UIImage imageNamed:#"card.png"]; //begin
int id=TarretWheel[r];
mCards[r].image = gCardImages[id]; //end
// Start animtion
[UIView commitAnimations];
// show view
mBackground.hidden=false;
You can (and preferably should, actually), be using the newer block-based animation methods on UIView. Check out the following (it has a completion block which is just what you need):
[UIView animateWithDuration:0.5 animations:^{
} completion:^(BOOL finished) {
}];
Edit:
There are other variants with options that you may want in your case.
Also, clarification on why you 'should' be using the block-based methods; from the docs (for beginAnimations:context:):
Use of this method is discouraged in iOS 4.0 and later. You should use
the block-based animation methods to specify your animations instead.
My answer is same as Joe but I would recommend using a different API which allows you with configure block.
[UIView animateWithDuration:2
delay:0.0
options:UIViewAnimationOptionTransitionFlipFromLeft|UIViewAnimationOptionCurveEaseOut |
animations:^{
// mCards[0].image = [UIImage imageNamed:#"card.png"]; //begin
int id=TarretWheel[r];
mCards[r].image = gCardImages[id]; //end
}
completion:^(BOOL finished){
mBackground.hidden=false;
}
];
What is the simplest way to create a custom UIView animation transition? Most of the tutorials that pop up in a Google search are not recent. (I'm using XCode 4.5 version) In my current iPhone app I have the following code for my screen transitions:
[UIView beginAnimations:#"View flip" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.25];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[UIView commitAnimations];
I want something unique instead of the 5 or 6 built-in transitions. Any ideas or suggestions on where to start?
I think this is what you are looking for:
[UIView animateWithDuration:0.3 animations:^{
//Move frame or transform view
}];
Inside that block you can put arbitrary animation code.
In my -application:DidFinishLaunchingWithOptions, as the final part, I have this code:
[UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionCurveEaseOut
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.viewController.source cache:YES];
self.viewController.source.alpha = 1.0;
} completion:nil];
What it should do is "fade in the 'source' view and curl it down to cover the background"
Instead it just fades in the 'source' view, no curl.
Clues?
Solved:
It appears that parts of the animation loop isn't yet running at that point. Solution was to put the animation in a method, then from the application:DidFinishLaunchingWithOptions do
Having a puzzling problem. I have a universal app with a lot of shared code between the iPad and iPhone versions. There are different layouts in the nibs but essentially the same views and view hierarchy - one UIView used as a container for two sibling UITextViews.
UIView mainView with children:
UITextView passageTextView
UITextView notesTextView
One UITextView is hidden, the other visible.
The following is my code. The section commented out was my original animation attempt. This worked just as desired on the iPad, but not on the iPhone. The uncommented section is take 2, using the method recommended in the docs. The uncommented code does not work on either the iPad or iPhone - it hides/unhides my views but without any animation. If I add code to the completion block that also gets executed, so it's doing something, just not animating.
/*
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:mainView cache:YES];
passageTextView.hidden = YES;
notesTextView.hidden = NO;
[UIView commitAnimations];
*/
UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationTransitionFlipFromRight;
[UIView transitionWithView:mainView
duration:1.0
options:options
animations:^{ passageTextView.hidden = YES; notesTextView.hidden = NO; }
completion:NULL];
Edit: Still working on the problem, hoping someone has a suggestion.
Additional update
Figured out why the following was not working in the iPhone:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:mainView cache:YES];
passageTextView.hidden = YES;
notesTextView.hidden = NO;
[UIView commitAnimations];
I had neglected to wire the view to mainView in Interface Builder. Hours debugging and I just now thought to check that.
But, I still do not know why animation blocks are not working for either the iPhone or iPad. I have tried several approaches but I'm not getting any animation even though the show/hides are working.
I think you are using the wrong animation option.
Replace your second animation option by UIViewAnimationOptionTransitionFlipFromLeft (note the Option between Animation and Transition)
I believe that UIViewAnimationTransitionFlipFromLeft (which is what you have in your code) is a UIViewAnimationTransition not a UIViewAnimationOptions.
I'm trying to add a continuous animation onto my UITableViewCell-Subclass.
It's a rather easy one with an Image fading in and out (fading between 0.4 alpha and 1.0),
what I've tried so far ist the following:
-(void)animateRecordingIndicator{
[UIView beginAnimations:#"RecordingIndicatorAnimation" context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished)];
if (animatedImageView.alpha == 0.4)
animatedImageView.alpha = 1.0;
else
animatedImageView.alpha = 0.4;
[UIView commitAnimations];
}
the code within animationFinished is as follows:
-(void)animationFinished{
if (doShowAnimation) {
[self performSelectorOnMainThread:#selector(animateRecordingIndicator) withObject:nil waitUntilDone:YES];
}
}
what I expect should be clear by now, but what I get is simply a crash with Xcode loading Stackframes more or less eternally :)
According to the UIView class reference, you are now discouraged from using the commitAnimations method. Instead use the following:
animateWithDuration:delay:options:animations:completion:
I imagine the infinite recursion you are encountering is related to Apple's reasons for making that recommendation.