Recursive animateWithDuration: animations: completion: method iOS - ios

I am attempting to make my item "glow" every 3 seconds changing its alpha from a high to low value and back. It however "flickers" and basically changes every 0.2 seconds from color to color randomly. I have pasted the method below. Its probably something to do with when completion is called but not sure?
-(void)showLoading{
[self.postTableView setHidden:YES];
self.isLoading = true;
//Disappear
[UIView animateWithDuration:1.5 animations:^(void) {
self.loadingLabel.alpha = 0.8;
self.loadingLabel.alpha = 0.3;
}
completion:^(BOOL finished){
//Appear
[UIView animateWithDuration:1.5 animations:^(void) {
self.loadingLabel.alpha = 0.3;
self.loadingLabel.alpha = 0.8;
}completion:^(BOOL finished2){
if(true){
[self showLoading];
}
}];
}]; }

self.loadingLabel.alpha = .8;
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
self.loadingLabel.alpha = .3;
} completion:nil];
UIViewAnimationOptionAutoreverse & UIViewAnimationOptionRepeat can help you.
you can stop it by
self.loadingLabel.alpha = .8;
or the other animation.
[UIView animateWithDuration:1.5 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.loadingLabel.alpha = .8;
} completion:nil];
UIViewAnimationOptionBeginFromCurrentState is a useful option for you to stop your animation by the other animation.

-(void)viewDidLoad{
//use schedule timer to call repeatedly showLoading method until loading done
}
-(void)showLoading{
[self.postTableView setHidden:YES];
self.isLoading = true;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.loadingLabel.alpha = 0.3;
[UIView commitAnimations];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
self.loadingLabel.alpha = 0.8;
[UIView commitAnimations];
}

Related

Animating Labels with delay and duration Ios

So i was trying to animate label which will start with a text then after certain time it will fade and new text comes to the screen which will fade after certain time and then new text comes. I want this to happen recursively. I need to continue animating for 15 seconds , the again same thing happens for next 15 seconds.
- (void)viewDidLoad {
[super viewDidLoad];
[self MyLabelAnimation];
}
- (void)MyLabelAnimation {
self.myLabel.text = #"Text 1";
[UIView animateWithDuration:0.3 animations:^{
self.myLabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myLabel.alpha = 0.0;
} completion:^(BOOL finished) {
self.myLabel.text = #"Text 2";
[UIView animateWithDuration:0.3 animations:^{
self.myLabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myLabel.alpha = 0.0;
} completion:^(BOOL finished) {
self.myLabel.text = #"Text 3";
[UIView animateWithDuration:0.3 animations:^{
self.myLabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myLabel.alpha = 0.0;
} completion:^(BOOL finished) {
self.myLabel.text = #"Text 4";
[UIView animateWithDuration:0.3 animations:^{
self.myLabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.0 delay:4.8 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myLabel.alpha = 0.0;
} completion:^(BOOL finished) {
[self MyLabelAnimation];
}];
}];
}];
}];
}];
}];
}];
}];
}
So Here i am calling mylabel animation from viewdidload and then i called the method at the end of the completion block of 4th animation.
Here everything is working as expected but the last animation to first animation transition is not smooth as other transition. Is it because i missed something . I really am not able to figure out why is it happening.
Secondly, Is is the right way to get the animation like this. Or is there a better way to do this ?
You might find something like this a bit easier to manage:
- (void)viewDidLoad {
[super viewDidLoad];
self.counter = 0;
self.animations = #[
#{#"Text":#"Hello", #"Duration":#(2.7)},
#{#"Text":#"Text 1", #"Duration":#(2.7)},
#{#"Text":#"Text 2", #"Duration":#(2.7)},
#{#"Text":#"Text 3", #"Duration":#(2.7)},
#{#"Text":#"Text 4", #"Duration":#(4.8)},
];
[self animate:0];
}
- (void)animate:(int)counter {
self.counter = counter % self.animations.count;
NSDictionary *item = self.animations[self.counter];
self.myLabel.alpha = 0;
self.myLabel.text = item[#"Text"];
[UIView animateWithDuration:0.3
animations:^{
self.myLabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3
delay:[item[#"Duration"] floatValue]
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.myLabel.alpha = 0.0;
} completion:^(BOOL finished) {
[self animate:++self.counter];
}];
}];
}
Try this code....
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(MyLabelAnimation:) userInfo:nil repeats:NO];
}
- (void)MyLabelAnimation:(NSTimer*) timer {
self->mylabel.text = #"Hello";
[UIView animateWithDuration:0.3 animations:^{
self->mylabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self->mylabel.alpha = 0.0;
} completion:^(BOOL finished) {
self->mylabel.text = #"Text 2";
[UIView animateWithDuration:0.3 animations:^{
self->mylabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self->mylabel.alpha = 0.0;
} completion:^(BOOL finished) {
self->mylabel.text = #"Text 3";
[UIView animateWithDuration:0.3 animations:^{
self->mylabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.3 delay:2.7 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self->mylabel.alpha = 0.0;
} completion:^(BOOL finished) {
self->mylabel.text = #"Text 4";
[UIView animateWithDuration:0.3 animations:^{
self->mylabel.alpha = 1.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.0 delay:4.8 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self->mylabel.alpha = 0.0;
} completion:^(BOOL finished) {
[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:#selector(MyLabelAnimation:) userInfo:nil repeats:NO];
}];
}];
}];
}];
}];
}];
}];
}];
}

UiViewAnimation not call setAnimationDidStopSelector

I created this animation and I entered through the stop animation
[UIView setAnimationDidStopSelector:#selector (TermineAnimazioneGoPointAssignedWithDelay)] ;
When the animation part of the SetAnimationDidStop is not called ... Can you tell me why and where am I doing wrong ?
This is all the way animation :
-(void)setViewStatusGoPointassigned {
ViewgoPointAssignMessage = [[UIView alloc] initWithFrame:CGRectMake(115, 150, 100, 100) ];
ViewgoPointAssignMessage.backgroundColor = [UIColor colorWithRed:(77/255.0) green:(108/255.0) blue:(143/255.0) alpha:(1)];
[ViewgoPointAssignMessage.layer setCornerRadius:10.0f];
[ViewgoPointAssignMessage.layer setMasksToBounds:YES];
[UIView animateWithDuration:0.2 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(1.05, 1.05);
ViewgoPointAssignMessage.alpha = 0.8; }
completion:^(BOOL finished){
[UIView animateWithDuration:2/15.0 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformMakeScale(0.9, 0.9);
ViewgoPointAssignMessage.alpha = 0.9; }
completion:^(BOOL finished) {
[UIView animateWithDuration:1/7.5 animations:^{
ViewgoPointAssignMessage.transform = CGAffineTransformIdentity;
ViewgoPointAssignMessage.alpha = 1.0; } ];
} ];
} ];
[self.view addSubview:ViewgoPointAssignMessage];
[UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)];
}
-(void)TermineAnimazioneGoPointAssignedWithDelay {
[self performSelector:#selector(EliminazioneViewAfterDelay) withObject:self afterDelay:0.01];
}
-(void)EliminazioneViewAfterDelay {
CGRect endREct;
endREct = CGRectMake(350 , 0 , 330, 90);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.005];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(EliminaAnimazione)];
ViewgoPointAssignMessage.frame = endREct;
[UIView commitAnimations];
}
- (void)EliminaAnimazione {
[ViewgoPointAssignMessage removeFromSuperview];
}
First of all, to answer your question.
You may try
[UIView animateWithDuration:(NSTimeInterval)duration animations:^(void)animations completion:^(BOOL finished)completion]
and call [self TermineAnimazioneGoPointAssignedWithDelay] in the completion.
Secondly, [UIView setAnimationDidStopSelector:#selector(TermineAnimazioneGoPointAssignedWithDelay)] doesn't work because according to the reference, setAnimationDidStopSelector must be called between calls to the beginAnimations:context: and commitAnimations methods. Since your code doesn't comply to this rule, the function does not work either.
Hopefully it explains! Good Luck!

Change backgroundColor of a view repeatedly and with animation

I am planning to do an app which has a continuous change of colors in the background. In my idea, there should be an UIView animation after the other one that should repeat itself again and again. This my attempt
self.view.backgroundColor = [UIColor whiteColor];
[UIView animateWithDuration:4 delay:0 options: UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse animations:^{
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.backgroundColor = [UIColor yellowColor];
NSLog(#"1");
} completion:^(BOOL finished){
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.backgroundColor = [UIColor greenColor];
NSLog(#"2");
} completion:^(BOOL finished){
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.backgroundColor = [UIColor redColor];
NSLog(#"3");
} completion:^(BOOL finished){
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.view.backgroundColor = [UIColor purpleColor];
NSLog(#"4");
} completion:NULL];
}];
}];
}];
} completion:NULL];
However this doesn't only look messy, but also doesn't repeat itself. Any advice?
Have an array of colours and a currentColorIndex property. Something which gives you the list of colours and a current position in the list. Now have a single method with a single animateWithDuration: in it. In that method, get the next colour and then update the index (wrapping back to 0 when it gets to the end) and run the animation. In the animation completion block, call the method again.

How do I have text fade in to a UILabel?

Right now I have an IBAction for a button which generates a random number with each number assigned to display text in a UILabel. Rather than just appear, I would like the text to fade in or any other interesting animation would be cool too. Does anyone know a simple way to make this happen?
Right now I just use
labelMain.text = #"my text";
I know this is a bit stale (11 months old), but I think it's worth mentioning an alternative to the other approaches posted, which I feel is a better solution.
Make use of the UIView transitionWithView:duration:options:animations:completion class-level method, like this:
NSTimeInterval duration = 0.5f;
[UIView transitionWithView:labelMain
duration:duration
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
labelMain.text = #"new value";
} completion:nil];
This will cross-fade from the previous value of labelMain.text to "new value".
This approach works on other view values as well, such as changing the image of a UIImageView, for instance.
See Apple's docs on the topic.
The following code will give you fading effect on your label.
- (IBAction)buttonClicked:(UIButton *)sender
{
labelMain.alpha = 0;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn
animations:^{ labelMain.alpha = 1;}
completion:nil];
}
label.text = #"old text";
[UIView animateWithDuration:0.4 animations:^{
label.alpha = 0.0f;
} completion:^(BOOL finished) {
label.text = #"next text";
[UIView animateWithDuration:0.4 animations:^{
label.alpha = 1.0f;
} completion:^(BOOL finished) {
NSLog(#"finished transition");
}];
}];
Try this:
[labelMain setAlpha:0];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.8];
[labelMain setAlpha:1];
[UIView commitAnimations];
Changing the duration is pretty simple - just adjust the value 0.8 in the code.
// fade out the current value
[UIView animateWithDuration:0.2
delay:0
options:0
animations:^{
labelMain.alpha = 0.0f;
}
completion:^(BOOL finished) {
// set the new value and fade in
labelMain.text = newValue;
[UIView animateWithDuration:0.2
delay:0
options:0
animations:^{
labelMain.alpha = 1.0f;
}
completion:nil];
}];
This will look like cross fade animation
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
labelMain.alpha = 0;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn
animations:^{ labelMain.alpha = 1;}
completion:nil];
} completion:nil];

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