Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView animateWithDuration: slows down animation frame rate

I am using CADisplayLink to draw frames using the EAGLView method in a game at 60 times per second.

When I call UIView animateWithDuration: the framerate drops down to exactly half, from 60 to 30 fps for the duration of the animation. Once the animation is over, the fps rises instantly back up to 60.

I also tried using NSTimer animation method instead of CADisplayLink and still get the same result.

The same behavior happens when I press the volume buttons while the speaker icon is fading out, so it may be using animateWithDuration. As I would like to be able to handle the speaker icon smoothly in my app, this means I can't just rewrite my animation code to use a different method other than animateWithDuration, but need to find a solution that works with it.

I am aware that there is an option to slow down animations for debug on the simulator, however, I am experiencing this on the device and no such option is enabled. I also tried using various options for animateWithDuration such as the linear one and the user interaction, but none had an improvement.

I am also aware I can design an engine that can still work with a frame rate that varies widely. However, this is not an ideal solution to this problem, as high fps is desirable for games.

Has someone seen this problem or solved it before?

like image 759
Michael Chinen Avatar asked Aug 02 '12 08:08

Michael Chinen


People also ask

Does UIView animate need weak self?

You don't need to use [weak self] in static function UIView. animate() You need to use weak when retain cycle is possible and animations block is not retained by self.

What is framerate in animation?

The 'frame rate' is also called the 'frames per second' (fps), and refers to the number of images we see in every second of an animated sequence or movie. If the fps is set too low, the animation will look choppy, as though the individual frames are being shown to us one by one.

Does UIView animate run on the main thread?

The contents of your block are performed on the main thread regardless of where you call [UIView animateWithDuration:animations:] . It's best to let the OS run your animations; the animation thread does not block the main thread -- only the animation block itself.

What is usingSpringWithDamping?

usingSpringWithDamping : This controls the amount of damping, or reduction, applied to the animation as it approaches its final state. This parameter accepts values between 0.0 and 1.0 .


1 Answers

The solution to this is to do your own animation and blit during the CADisplayLink callback.

1) for the volume issue, put a small volume icon in the corner, or show it if the user takes some predefined touch action, and give them touch controls. With that input you can use AVAudioPlayer to vary the volume, and just avoid the system control altogether. you might even be able to determine the user has pressed the volume buttons, and pop some note saying do it your way. This gets you away from any animations happening by the system.

2) When you have an animation you want to do, well, create a series of images in code (either then or before hand), and every so many callbacks in the displayLink blit the image to the screen.

like image 158
David H Avatar answered Oct 03 '22 17:10

David H