Is there a difference in the performance of UIView animation vs CA Animation blocks? I understand they are all interfaces to Core Animation, but am looking to squeeze the most performance vs resources per animation. Thanks.
You will have to benchmark them yourself to be sure, but my guess is there will be no difference. They are both using the same code under the covers and UIView and CALayers perform almost identically to each other. You'll get more performance by making sure you're handling alpha properly. Make everything opaque that can be. The less that has to be calculated through compositing the more responsive your animations will be.
Best regards.
Related
I am writing IOS app where many CALayers (hundreds) are displayed at the same time on screen. Update of interface (at rate about 50-60Hz) includes removing/adding some CALayers from/to layers hierarchy and changing "hidden" state of other CALayers. All updates are made under common CATransaction with ANY animations swithed off.
Frequent removing/adding CALayers from hierarchy doesn't lead to any problems with graphics performance. But frequent changing of "hidden" state of CALayers leads to degradation of FPS so graphics updates stop being smooth and stable. It seems that GPU always late with processing updated screen.
Does anyone know what is the reason for this effect? In official documentation there is no any word about such side effects of hiding/showing layers. Adding/removing and hiding/showing layers seem to have similar consequences to what is made with layers: when layer is hidden it is just not processed at all what is equivalent to being removed (except maybe that it is still cached somewhere in GPU..?). Maybe someone can explain that or faced the same problem?
I need to add a background where random clouds comes from the sides. This effect need to be almost in every screen of the app. I tried using animateWithDuration with UIImageViews but it consumes a lot of battery, and when I am on some screens with other extra animations, this animations look jerky.
Also tried using .gif and videos as background:
Video as background
But they are to heavy, since it has to be a long video in order to make it look like the clouds appears in random intervals. And also consumes a lot of resources.
Are there other ways to make this effect, like a lightweight animation technique?
I imagine your best bet would be to use a CALayer on your UIViews, it should be more lightweight than the UIImage solution.
In Android it is recommended that the view hierarchy depth be kept under 10, and strictly under 20 or else your app is very likely to perform poorly or crash (UI thread only a tiny 8-16kB of stack space)
Does this hold true for iOS, with or without autolayout (why or why not) ?
Views in iOS are backed by OpenGL and have amazing performance. I've personality gone as deep as 50 views with no problems. I don't recommend making the depth bigger than necessary, but when the situation calls for it, it is viable.
Update:
It is actually quite bad if you are using autolayout, as constraints solving has polynomial complexity (cassowary is linear in the sense that it solves linear equations)
http://floriankugler.com/2013/04/22/auto-layout-performance-on-ios/
http://pilky.me/36/
UIView itself is very fast as posts here suggest, however. I ended up replacing autolayout with an alternative system.
TLDR: UIView/CALayer is fast. Autolayout is not.
I've never seen any such recommendation for iOS. As always, you should implement your code and view hierarchy as straightforward as possible. After that, measure your performance and tweak if needed. Avoid premature optimization as much as possible.
My first question on StackOverflow. So feeling kind of shy ...
I've been working and tweaking on an curstom control for some weeks now. It uses ±6 subclassed CALayers for some fancy animations to give the best possible user-feedback. Additionally there are 2 animated UIViews adding up to some heavy animation and redrawing during user interaction.
I managed to get the responsiveness and performance on an iPhone 5S up to +50fps. But on a iPhone 4, it really makes me cry: 8 ~ 15fps. I tried to figure out what causes this awfull performance, but till now I found nothing other than the fact I might be wanting to much from Core Animation.
Using layer.drawsAsynchronously = YES; on all CALayers increased the responsiveness by A LOT. And I also took out all unnecessary animations (including implicit animations). But it still isn't enough. The performance on an iPhone 4 is still not the way I want it.
I notice a lot of improvement when I switch to layer.opaque = YES; But due to the design of my interface, this really isn't an option.
Is there anyting you guys can suggest to look into? Are there any other "magic" properties, like .drawsAsynchronously I might want to try or look into?
Are there any resources you can suggest on how to debug/analyse the performance?
Any help is appriciated. Thanks in advance!
The quickest answer will be don't use drawRect: because it's very expensive.
CALayers are the best way.
If you need to draw something complex is good to consider Core Graphics because it use GPU instead of CPU which is much more effective. You can draw image with Core Graphics and add it to the view.
Have a look on this link
There is good explanation how UIView works and how to write most efficient code
I am wondering if what I'm attempting is just a bad idea. I'm currently working in monotouch. Is it possible to draw a screen-sized (on my iPhone 4 its about 320x460) buffer onto a UIView of equal size fast enough so that animated changes to that buffer look smooth to the end user (need it to be around 20ms per draw).
I've attempted many different implementations. The best one so far seems to be using an in-memory CGLayer and calling context.DrawLayer() to apply it to the view inside of Draw(). But even that takes 30-40ms per DrawLayer.
I'm writing my own tile-image control, and aside from performance, the idea is working well. I just can't figure out how to get the buffer onto the UIView fast enough.
Any ideas?
I've been dealing with custom views a lot lately, and i've had a bunch of performance problems, too.
All of these performance issues could be solved by determining the elements that need to be redrawn, and, more importantly, the elements that do not need to be redrawn.
Then, split the contents in the layer into individual sublayers and only redraw them if necessary. The good thing is, animations and so on are very smooth for those individual layers. (Their content is only a simple bitmap and does not change until you tell it to).
The only limitation i've come across was, that you cannot use CG blend modes (e.g. multiply) for the sublayers. As far as i know that is not possible. You can only use those blend modes inside the CG code used to draw the contents of the sublayers, but after that they are all composed in "normal" mode.
It really depends on what you are drawing.
If you are just drawing a solid filled color, that should not be a problem. The question is how much of the surface you are changing, and how you are changing it.
Again, it depends on what you are drawing and whether you could offload some of the work to the GPU. For example if you have static parts of your interface that will remain the same, or are animated/updated independently, you could use a different layer for those areas and let the GPU compose those.
Layers have the advantage that they are composited by the GPU, and they are backed by their own bitmaps. Once you draw into the surface of the layer, the OS will cache the result in the GPU and compose all of your layers at the same time.
Then you can determine which parts of your application actually need to be redrawn and only redraw those sections on each frame.
But again, it really will depend a lot on what you are trying to do.