Fade animation inside for-loop - ios

At least I would dream of this Animation Flow:
FadeIn to 50% with alpha:0.5 for 2 seconds
Then fadeIn to 100% with alpha:1 for 2 seconds
Then fade out to 0% with alpha:0 for 4 seconds
After the visible animation ends, the text for the label shall be changed and then the fade routine should start again as shown above.
I feel that this code here does not allow the step by step fade animation and the code commences too early without waiting to finish the Fade out section.
//A FOR Loop sets text for the _label then the Animation routine should start:
- (IBAction)startFade:(id)sender
{
[_label setAlpha:0.f];
[UIView animateWithDuration:2.f
delay:0.f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
[_label setAlpha:1.f];
}
completion:^(BOOL finished) {
[UIView animateWithDuration:2.f
delay:0.f
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[_label setAlpha:0.f];
}
completion:nil];
}
];
}
// Somehow the code shall wait here for ending the visible (!!) animation in the UI
// to set a new text for _label with the FOR Loop
The whole issue took me some days to figure out so far. But I am stuck here with the problem to pause the code for a while as it does not automatically wait for the visual finishing of the animation which makes it difficult for me to go on.

I'm sure that is what you are really looking for; but it meets your description:
- (IBAction)startFade:(id)sender {
[_label setAlpha:0.f];
[UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveLinear animations:^{
[_label setAlpha:0.5f];
} completion:^(BOOL finished) {
NSLog(#"1st step is done.");
[UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveLinear animations:^{
[_label setAlpha:1.f];
} completion:^(BOOL finished) {
NSLog(#"2nd step is done.");
[UIView animateWithDuration:4.f delay:0.f options:UIViewAnimationOptionCurveLinear animations:^{
[_label setAlpha:0.f];
} completion:^(BOOL finished) {
NSLog(#"3rd step is done, text will be changed.");
// let me change the text
[_label setText:[[NSDate date] description]];
// let me start the animation over, welcome to my infinite loop.
[self startFade:nil];
}];
}];
}];
}

Related

Fade between text in a UILabel with delay

I want to animate the text of a UILabel so that it shows one text for a couple of seconds and after that fades into a default text.
I'm currently using the following code:
-(void)tapOnBalance:(id)sender{
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
cell.amountLabel.text = #"Hola!";
} completion:nil];
// Pause the function - act as a 'delay'
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
[UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
cell.amountLabel.text = #"Hallo!";
} completion:nil];
}
This works, but the [NSRunLoop currentRunLoop] is pausing the entire app, blocking everything for 3 seconds.
How do I get rid of the block on the main thread and still get the same result?
A simple fade (not a cross-fade) can go like this:
// change a label's text after some delay by fading
// out, changing the text, then fading back in
- (void)fadeLabel:(UILabel *)label toText:(NSString *)toText completion:(void (^)(BOOL))completion {
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
label.alpha = 0.0;
} completion:^(BOOL finished) {
label.text = toText;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
label.alpha = 1.0;
} completion:completion];
}];
}
// simpler signature that can be done on a perform
- (void)changeLabelText:(NSString *)toText {
[self fadeLabel:self.myLabel toText:toText completion:nil];
}
// set the label to something, then change it with a fade, then change it back
self.myLabel.text = #"text";
[self performSelector:#selector(changeLabelText:) withObject:#"hola!" afterDelay:4];
[self performSelector:#selector(changeLabelText:) withObject:#"text" afterDelay:8];
You could also nest the calls' completion blocks (and add a delay param) to do something similar without the performs. To do a cross-fade, apply a similar technique with two labels (that have the same frame) where one's alpha is zero and the other's alpha is one.

UIView Animation Move

I have managed to make the "view" move once. I need for it to stay 1 second in same place and then move back again to initial place. How would I add the rest of the code for this? (This won't be a loop, only done once)
[UIView animateWithDuration:0.8 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[infoView setCenter:CGPointMake(160,30)];
} completion:nil];
Use the completion block to do another animation:
[UIView animateWithDuration:0.8 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[infoView setCenter:CGPointMake(160,30)];
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.8 delay:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[infoView setCenter:CGPointMake(orignalX, originalY)];
} completion:nil];
}];

Lag between 2 animations

I am trying to animate one of my image form bottom to Top of my screen , for that i am implementing an animation that the current width and height of image will become half during the transition stage and will take its original size once animation completes.
The issue is once the 1st animation is done it hold's for a while and then starts another animation , i want a smooth animation .
Here is the code :
[UIView animateWithDuration:1.0
delay:0.5
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[_myImageView setFrame:CGRectMake(20.0, 220.0, currentframe.size.width/2, currentframe.size.height/2)];
} completion:^(BOOL finished)
{
if (finished)
{
[UIView animateWithDuration:1.0
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[_myImageView setFrame:CGRectMake(20.0, 20.0, currentframe.size.width, currentframe.size.height)];
} completion:^(BOOL finished) {
if (finished) {
NSLog(#"2 nd log ");
}
}];
NSLog(#"animation fisnished !!");
}
}];
What should be done ?
try this:
[UIView animateWithDuration:1.0
delay:0
options:UIViewAnimationOptionCurveLinear// use CurveLinear option
animations:^{
} completion:^(BOOL finished) {
}];

Apply some easing into UIImageView animation

I am using the following to make a UIImageView slide a little bit forward, and then slide back farther for a parallax scrolling effect.
Code:
[UIView animateWithDuration:0.2f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x + 20, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
[UIView animateWithDuration:0.4f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x - 80, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
I am wondering how I might go about applying some easing into the animation, right now if just abruptly slides back and forth quickly. I would like to ease into and out of the sliding animations.
You need to do the second animation block after the first one completes.
[UIView animateWithDuration:0.2f animations:^{
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x + 20, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
} completion:^{
[UIView animateWithDuration:0.2f animations:^(BOOL finished){
spendrBckGrnd.frame = CGRectMake(spendrBckGrnd.frame.origin.x - 80, 0, spendrBckGrnd.frame.size.width, spendrBckGrnd.frame.size.height);
}];
}];
This will do the trick:
[UIView animateWithDuration:0.2f delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^(void){
//do your animations
} completion:^(BOOL finished){
}];
Check out this tutorial on UIView animation
http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_uiview-animations/
UIView has a method
// [UIView animateWithDuration:(NSTimeInterval) delay:(NSTimeInterval) options:(UIViewAnimationOptions)animations:^(void)animations completion:^(BOOL finished)completion];
typedef enum {
UIViewAnimationCurveEaseInOut, // slow at beginning and end
UIViewAnimationCurveEaseIn, // slow at beginning
UIViewAnimationCurveEaseOut, // slow at end
UIViewAnimationCurveLinear
}
[UIView animateWithDuration:0.6f
delay:0.1f
options:UIViewAnimationCurveEaseInOut
animations:^{
[starView setCenter:CGPointMake(0, 0)];
[starView setAlpha:0.0f];
}
completion:^(BOOL finished){
[starView removeFromSuperview];
points++;
}
];
Also check out this control on github that creates a parallax effect using a custom container view, much like the top view of Path's timeline.
https://github.com/modocache/MDCParallaxView

UIViewAnimation plays instantly, delay is ignored

I have a simple UIViewAnimation that is called once my view is loaded.
However no matter what I place as the value for delay, it is ignored and the animation plays instantly.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:100.0];
[UIView setAnimationDelay:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(faceRight:finished:context:)];
_chooseLabelContainer.center = CGPointMake(originalCenter.x, 0 - _chooseLabelContainer.frame.size.height);
[UIView commitAnimations];
Update: As a test I've mangeled this scenario and below the non-delayed animation happens instantly, but the one within the dispatch queue animates overtime as expected!
UIView* objectToAnimate = self.hudController->_chooseLabelContainer;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
[UIView animateWithDuration:5.0 delay:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
NSLog(#"Start Dispatch %#", NSStringFromCGPoint( objectToAnimate.center ) );
objectToAnimate.center = CGPointMake(objectToAnimate.center.x, objectToAnimate.center.y+90);
}completion:^(BOOL done){
NSLog(#"Done Dispatch");
}];
});
[UIView animateWithDuration:5.0 delay:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
NSLog(#"Start %#", NSStringFromCGPoint( objectToAnimate.center ) );
objectToAnimate.center = CGPointMake( objectToAnimate.center.x, objectToAnimate.center.y+30);
}completion:^(BOOL done){
NSLog(#"Done");
}];
This might not solve your problem, but as of iOS 4 Apple recommends you use UIView animation blocks:
[UIView animateWithDuration:100.0 delay:2.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
_chooseLabelContainer.frame = CGPointMake(originalCenter.x, 0 - _chooseLabelContainer.frame.size.height);
}completion:^(BOOL done){
[self faceRight:finished:context]; //will of course generate errors since I don't know what arguments to pass.
}];

Resources