iOS Stuttering button Animation

IDMah

macrumors 6502
Original poster
May 13, 2011
288
9
Hmmm.. having trouble figuring this one out...
Debugging animation.. Sometimes it stutters sometimes it's perfect, sometimes it stutters like an angry drunk..

Code:
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
		scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
	
		scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.3, 0.3, 1.0)];
		scaleAnim.removedOnCompletion = YES;
	
		CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
		opacityAnim.fromValue = [NSNumber numberWithFloat:SetMoonBase];
		opacityAnim.toValue = [NSNumber numberWithFloat:0.1];
		opacityAnim.removedOnCompletion = YES;
	
		CAAnimationGroup *animGroup = [CAAnimationGroup animation];
		animGroup.duration = 0.4;
	
		if (animFunc==fadoutFunction) {
			animGroup.duration = 1.2;
			//[self performSelector:@selector(doNothing) withObject:nil afterDelay:2.0];
			
		}
		animGroup.animations = [NSArray arrayWithObjects:opacityAnim,scaleAnim,nil];
		[scaleAnim setDelegate: self];
		[[[buttonArray objectAtIndex:buttonNumber] layer] addAnimation:animGroup forKey:@"fadeout"];
Works perfectly on the simulator but on iphone 4 + iOS 5.1.1 more stutter than works.
I disable the button on once clicked.
any ideas anyone.. ???
 
Last edited:

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
Hmmm.. having trouble figuring this one out...
Debugging animation.. Sometimes it stutters sometimes it's perfect, sometimes it stutters like an angry drunk..

Code:
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
		scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
	
		scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.3, 0.3, 1.0)];
		scaleAnim.removedOnCompletion = YES;
	
		CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
		opacityAnim.fromValue = [NSNumber numberWithFloat:SetMoonBase];
		opacityAnim.toValue = [NSNumber numberWithFloat:0.1];
		opacityAnim.removedOnCompletion = YES;
	
		CAAnimationGroup *animGroup = [CAAnimationGroup animation];
		animGroup.duration = 0.4;
	
		if (animFunc==fadoutFunction) {
			animGroup.duration = 1.2;
			//[self performSelector:@selector(doNothing) withObject:nil afterDelay:2.0];
			
		}
		animGroup.animations = [NSArray arrayWithObjects:opacityAnim,scaleAnim,nil];
		[scaleAnim setDelegate: self];
		[[[buttonArray objectAtIndex:buttonNumber] layer] addAnimation:animGroup forKey:@"fadeout"];
Works perfectly on the simulator but on iphone 4 + iOS 5.1.1 more stutter than works.
I disable the button on once clicked.
any ideas anyone.. ???


Are you using shadows? Those wreak havoc with animations, and can make them stutter like mad. If you are, try turning off all your shadows and test.

If that speeds things up, you know what the problem is.

If you feel shadows are critical to the look of your app, you might need to try a few tricks

  • Turn off shadows at the beginning of an animation, then turn them back on after it's over.
  • Rasterize your shadow layer into a fixed bitmap for the duration of the animation. Turn off system-based shadows and add the shadow bitmap as a layer to your layer hierarchy so it looks correct, then do your animation. Once the animation is complete, remove the shadow bitmap and turn shadows back on.
 

IDMah

macrumors 6502
Original poster
May 13, 2011
288
9
What's the easiest way to turn off the TextShadow???

would
Code:
[[buttonArray objectAtIndex:buttonNumber] setTitleShadowColor:nil forState: UIControlStateNormal]
be the same as setting the offset to (0,0) ??
Does that even turn off (disable it ?) the shadow or do I have to change something in the dictionary??

I would like just some bool, so it will be easy to setback after animation is
done.

thanks
Ian
 
Last edited:

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
What's the easiest way to turn off the TextShadow???

would
Code:
[[buttonArray objectAtIndex:buttonNumber] setTitleShadowColor:nil forState: UIControlStateNormal]
be the same as setting the offset to (0,0) ??
Does that even turn off (disable it ?) the shadow or do I have to change something in the dictionary??

I would like just some bool, so it will be easy to setback after animation is
done.

thanks
Ian

I don't think text shadows are the problem. I believe that text shadows actually cheat and create a second copy of the label that is offset slightly behind the main label, and a different color. They're not partly transparent, and don't extend outside the bounds of the view. Shadows on CALayers, on the other hand, are partly transparent AND extend outside the layer's bounds, so the system has to composite the partly transparent areas by calculating every value of every pixel, which is very slow.


Post your animation code that stutters.

It might not be shadows - there are other things that could be causing your slowdowns.
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
I think that's what the code from their original post is.
Oops. My bad. That's teach me not to review a post before re-posting to it...

To the OP, I don't see anything obvious wrong with your animation code.

As somebody else said, UIView animation is much simpler to do, and therefore less error-prone. You might try that. You could get the same effect with UIView animation in about 3 lines of code.



EDIT: OK, more like 6 lines of code:

Code:
CALayer *buttonLayer = [buttonArray  objectAtIndex:buttonNumber].layer;
[UIView animateWithDuration: .5 delay: 0 options: 0 animations: 
^{
  buttonLayer.transform = CATransform3DMakeScale(0.3, 0.3, 1.0);
  buttonLayer.opacity = 1.0;
  }
completion: 
^{
  //Restore the values to their original settings one the animation is complete. 
  //to give the same effect as removeOnCompletion = YES
  buttonLayer.transform = CATransform3DIdentity;
  buttonLayer.opacity = SetMoonBase;
  }
];
I wasn't quite sure what your "doNothing" code was all about, so I didn't attempt to handle that part.
 
Last edited:

IDMah

macrumors 6502
Original poster
May 13, 2011
288
9
Dude!!! thanks .. your making me a blocks believer !!!

just for those who may be referencing this .. here is the block code. with the BOOL

Code:
   CALayer *buttonLayer = [[buttonArray objectAtIndex:buttonNumber] layer];
        [UIView animateWithDuration: 0.7 delay: 0 options: 0 animations: 
         ^{
             buttonLayer.transform = CATransform3DMakeScale(0.3, 0.3, 1.0);
             buttonLayer.opacity = 0.10;
         }
        completion:
        ^(BOOL  completed){ // <---------- *******
             //Restore the values to their original settings one the animation is complete. 
             //to give the same effect as removeOnCompletion = YES
             buttonLayer.transform = CATransform3DIdentity;
             buttonLayer.opacity = SetMoonBase;
            [[buttonArray objectAtIndex:buttonNumber] setAlpha:0.10];
         }
         ];
thanks agin.. now I'm going to convert all my animation to blocks..
so much simpler and wicked fast..

thanks
Ian
 

Duncan C

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
Dude!!! thanks .. your making me a blocks believer !!!

just for those who may be referencing this .. here is the block code. with the BOOL

Code:
   CALayer *buttonLayer = [[buttonArray objectAtIndex:buttonNumber] layer];
        [UIView animateWithDuration: 0.7 delay: 0 options: 0 animations: 
         ^{
             buttonLayer.transform = CATransform3DMakeScale(0.3, 0.3, 1.0);
             buttonLayer.opacity = 0.10;
         }
        completion:
        ^(BOOL  completed){ // <---------- *******
             //Restore the values to their original settings one the animation is complete. 
             //to give the same effect as removeOnCompletion = YES
             buttonLayer.transform = CATransform3DIdentity;
             buttonLayer.opacity = SetMoonBase;
            [[buttonArray objectAtIndex:buttonNumber] setAlpha:0.10];
         }
         ];
thanks agin.. now I'm going to convert all my animation to blocks..
so much simpler and wicked fast..

thanks
Ian
The general rule I'd recommend is to try to do things with UIView block animations. If you can, go for it.

There are things you can't do with view animations, though, and for those, you need to dive into CAAnimation objects. They are much more powerful, but a lot harder to use. Also, view animations are fine-tuned by Apple, so they tend to be fast. There's more control with CAAnimation objects, but there's also more opportunity for doing things inefficiently.