ios removeAllAnimations not working - ios

I have an forever animation, but I want to stop it at some point I tried removeAllAnimations but it did not work.
Here is my code.
[self.backgroundImageView.layer removeAllAnimations];
-(void)animateToLeft{
if(isInCenter){
[UIView animateWithDuration:10.0f animations:^{
backgroundImageView.frame = CGRectMake(kLeftX, 0, kBackgroundWidth, kBackgroundHeight);
}completion:^(BOOL finished) {
[self animateToRight];
}];
isInCenter = NO;
}
else{
[UIView animateWithDuration:20.0f animations:^{
backgroundImageView.frame = CGRectMake(kLeftX, 0, kBackgroundWidth, kBackgroundHeight);
}completion:^(BOOL finished) {
[self animateToRight];
}];
}
}
-(void)animateToRight{
[UIView animateWithDuration:20.0f animations:^{
backgroundImageView.frame = CGRectMake(kRightX, 0, kBackgroundWidth, kBackgroundHeight);
}completion:^(BOOL finished) {
[self animateToLeft];
}];
}

This will not work in your situation.
Because [self.backgroundImageView.layer removeAllAnimations]; this will remove all layer animation which already have added by [self.backgroundImageView.layer addAnimation:/*CABasicAnimation should added here*/];
You can stop this cycle by set boolean variable in completion, then check with boolean variable.

Use a boolean value and if that is set, don't do the next animation -- also cancel pending ones..
e.g.
#interface MyClass () {
BOOL cancelAll;
}
#implementation MyClass
-(void)cancelAnimation {
self.imageView.layer removeAllAnimations]; //!
cancelAll = YES;
}
-(void)animateToLeft{
if(cancelAll)
return;
...
}
-(void)animateToRight{
if(cancelAll)
return;
...
}

Related

Continous fade in and fade out

Im trying to fade in and out of a light node I have created I just dont know where to call the function accordingly so it will continously fade in and out. Never tried animating anything here is what I have.
- (void)fadeOutIn:(UIView *)view duration:(NSTimeInterval)duration
{
[self enumerateChildNodesWithName:#"//*" usingBlock:^(SKNode *node, BOOL *stop) {
if ([node.name isEqualToString:#"light1"]) {
[UIView animateKeyframesWithDuration:5 delay:2 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationCurveEaseInOut animations:^{
node.alpha = 0;
} completion:^(BOOL finished) {
}];
}
}];
}
where should I call this function?that is fades in and out continously?
Should it be called within an action?
Thank You
Use this for Continue fade in out.
-(void)viewDidAppear:(BOOL)animated{
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationCurveEaseInOut|UIViewAnimationOptionAllowUserInteraction animations:^{
node.alpha = 0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1 animations:^{
node.alpha = 1;
} completion:nil];
}];
}
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[objAnimate setAlpha:1.0];
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
[objAnimate setAlpha:0.0];
} completion:nil];
}
This will create continuous fade in and out for your object when it appears. If you want to create programmatically a custom object and then use this code then do it after your custom object is added in your view as below (example):
objAnimate = [[UILabel alloc] initWithFrame:CGRectMake(20, 50, 200, 40)];
objAnimate.backgroundColor = [UIColor lightGrayColor];
[objAnimate setAlpha:1.0];
[self.view addSubview:objAnimate];
[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse animations:^{
[objAnimate setAlpha:0.0];
} completion:nil];
The view starts animating as soon as its added in your view.

Create UIView Animation that will loop after the completion method is run

I'm having a bit of trouble. I've set my UIView Animation to repeat itself infinitely, however it does this before the animation starts it's completion function. I want it to wait until after the completion function fully runs because I want to run multiple animations. Any idea how to do this? If not is there a different way I can accomplish the same thing?
I'll post my code below:
-(void) createBlueControlAnimation:(int)messageCount{
if(messageCount == 0) {
return;
}
[blueControl setContentOffset:CGPointMake(0, 0)];
[UIView animateWithDuration:0.5 delay:2 options:UIViewAnimationOptionRepeat
animations:^{
[blueControl setContentOffset:CGPointMake(screenWidth, 0)];
} completion:^(BOOL finished){
if(messageCount >= 2){
[UIView animateWithDuration:0.5 delay:2 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
[blueControl setContentOffset:CGPointMake(screenWidth * 2, 0)];
} completion:^(BOOL finished){
if(messageCount == 3) {
[UIView animateWithDuration:0.5 delay:2 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
[blueControl setContentOffset:CGPointMake(screenWidth * 3, 0)];
}completion:^(BOOL finished){
[self scrollAnimationToStart];
}];
}else{
[self scrollAnimationToStart];
}
}];
}else{
[self scrollAnimationToStart];
}
}];
}
-(void) scrollAnimationToStart {
[UIView animateWithDuration:0.5 delay:2 options:UIViewAnimationOptionAllowAnimatedContent
animations:^{
[blueControl setContentOffset:CGPointMake(0, 0)];
} completion:^(BOOL finished){}];
}
So based on the number of messages I want the animation to continue running, and then when it gets to the last message, loop back to the first message and then restart the animation. However right now it just loops infinitely between the first and the second message. Any ideas on how to fix this would be greatly appreciated, thanks.
Firstly: You should create separate consts for anything that is in code.
extern NSTimeInterval const animationDuration;
NSTimeInterval const animationDuration = 0.5;
extern NSTimeInterval const animationDelay;
NSTimeInterval const animationDelay = 2;
Secondly: intent your code in reasonable way, it's quite hard to read what you've pasted. Use one method and push every repeatable part of code into another method.
- (void)createBlueControlAnimation:(NSUInteger)messageCount {
if (messageCount == 0) {
return;
}
__weak typeof(self) weakSelf = self;
[self offsetBlueControl:0];
[UIView animateWithDuration:animationDuration delay:animationDelay options:UIViewAnimationOptionAllowAnimatedContent animations:^{
[weakSelf offsetBlueControl:screenWidth];
} completion:^(BOOL finished) {
if (messageCount < 2) {
[self scrollAnimationToStart];
} else {
[UIView animateWithDuration:animationDuration delay:animationDelay options:UIViewAnimationOptionAllowAnimatedContent animations:^{
[weakSelf offsetBlueControl:screenWidth * 2];
} completion:^(BOOL finished) {
if (messageCount != 3) {
[self scrollAnimationToStart];
} else {
[UIView animateWithDuration:animationDuration delay:animationDelay options:UIViewAnimationOptionAllowAnimatedContent animations:^{
[weakSelf offsetBlueControl:screenWidth * 3];
} completion:^(BOOL finished) {
[self scrollAnimationToStart];
}];
}
}];
}
}];
}
- (void)scrollAnimationToStart {
[UIView animateWithDuration:animationDuration delay:animationDelay options:UIViewAnimationOptionAllowAnimatedContent animations:^{
[blueControl setContentOffset:CGPointMake(0, 0)];
} completion:^(BOOL finished) {}];
}
- (void)offsetBlueControl:(CGFloat)xOffset {
[blueControl setContentOffset:CGPointMake(xOffset, 0)];
}
I should mention here that this animation block is in fact similar everywhere. I'd set it as a separate method also.
Thirdly, keep same way of spacing everywhere (eg check out https://github.com/NYTimes/objective-c-style-guide).
That's all about code, the quality, readibility etc. I'd set it as comment, but there's too much code in my response, so it has to be an answer.
I don't fully understand what do you want to do. As far as I understood:
You have a UI element, called BlueControl.
You want to move this element.
Basing on some counter you want to move your view by some width (btw I advise to switch to NSIntegers from ints and use unsigned option, so NSUInteger etc). The move steps:
3.1. Move button right during 0.5s
3.2. Wait 2 seconds if counter is large enough, otherwise end step 3
3.3. Increase counter, repeat step 3.
You want to repeat the process infinitely.
Is that right? I need to understand the problem to edit this answer and paste a full response here.

Init object in -(void) method

I have two classes for view controller, classA and classB that is subclass of classA.
In the classA, I write a method startAnimation that allow to display view like ActivityIndicator;
I tried to use -(void)startAnimation in classB by calling [self startAnimation], it did not work well but changing to -(BOOL)startAnimation works well. I haven't understood yet. Please explain for me:
-(BOOL)startAnimation{
__block bool a = NO;
_displayViewForActivityIndicator = [[ProcessingIndicationView alloc] initWithFrame:CGRectMake(-self.view.frame.size.width, -self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:_displayViewForActivityIndicator];
LogDebug(#"Start the method");
[UIView animateWithDuration:1.0f
delay:0.0f
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
//end position:
_displayViewForActivityIndicator.frame = self.view.frame;
}
completion:^(BOOL finished) {
if (finished) {
LogDebug(#"Finish animation");
}
a = YES;
}];
return a;
}

UIView multiple animations with different durations

I have a background UIImageView which is constantly animating with this code that gets called at the end of ViewDidAppear:
- (void)beginBackgroundAnimation
{
[UIView animateWithDuration:45
delay:0
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{
_background.frame = CGRectMake(-_background.frame.size.width + self.view.frame.size.width,
_background.frame.origin.y,
_background.frame.size.width,
_background.frame.size.height);
}
completion:nil];
}
The problem is, when I perform another animation, such as this:
[UIView animateWithDuration:delay animations:^{
registerRowView.alpha = 1;
registerRowView.frame = newFrame; // this line kills the animation
}];
The background animation resets to it's original state and stops animating..
Thank you in advance!
Try this:
Keep a bool variable globally like: BOOL isFirstAnimationCompleted; and set it false in the starting of the first animation.
[UIView animateWithDuration:45
delay:0
options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^{
_background.frame = CGRectMake(_background.frame.size.width + self.view.frame.size.width,
_background.frame.origin.y,
_background.frame.size.width,
_background.frame.size.height);
}
completion:^(BOOL finished) {
if(finished) {
isFirstAnimationCompleted = finished;
}
}];
Check while the user wants to perform the second animation like:
if(isFirstAnimationCompleted) {
[UIView animateWithDuration:delay animations:^{
registerRowView.alpha = 1;
registerRowView.frame = newFrame; // this line kills the animation
}];
}

UIView animation hide and show

I am begining to use UIView animation. And can't get such code working properly. Here is what i have
if(_Language.hidden == true)
{
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
_Language.alpha = 1.0;
}
completion:^(BOOL finished) {
_Language.hidden = false;
}];
}
else
{
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
_Language.alpha = 0.0;
}
completion:^(BOOL finished) {
_Language.hidden = true;
}];
}
This code works in such way. Hide animation works as expected. But show animation just waits 1 sec, and pops the object without any transition. Can anyone tell me what I am missing here?
You are changing the hidden attribute to true only after the animation is over, so it doesn't appear until the animation is completed. you should do it before the animation begins :
if(_Language.hidden == true)
{
_Language.hidden = false;
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationCurveEaseInOut
animations:^ {
_Language.alpha = 1.0;
}];
}
Your _Language.hidden is set as true and hence when it is animating, nothing will appear on the screen. You need to make it visible before animating. Set the hidden property to false and then show the animation. The reverse will work only for hiding when you add it in completion block.
_Language.hidden = false;
[UIView animateWithDuration:1.0 ...
and remove it from completion block,
completion:^(BOOL finished) {
}];

Resources