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
Related
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.
I am working on an app that needs to change a lot of CATextLayers strings, but, only one or two characters of it(in general though, the strings are in length of about 2-5 characters).
At first I went with UILabels which were extremely slow, and because of that I tried out CATextLayer, which was a lot faster, but not fast enough, I am updating about 150 CATextLayers quite often, all at once , and it just doesn't cut it, I feel a lag.
I then tried out to do it even more low-level with CoreText, I tried drawing it with a CTLine, which had about the same performance of CATextLayer, so I got back to the CATextLayers because my positioning code for CoreText wasn't perfect.
I started thinking about caching for each string the first two characters(which are always constant), and only changing the other 3 characters, with smaller bounds, which I assume will be a bit faster, but, will it be faster? After all it will have it to composite it with the other text-layer, and it will have to be update all of the 150 text-layers.
Does anybody have any advice? How would you approach it?
Attached is a screenshot from instruments showing that the problem lies in the performance of CATextLayer:
Bitmap Fonts are probably the best way to solve this problem, as they're far and away more performant than anything else in terms of font drawing for something of this nature. But you need to pre-render them to the scale you desire to get the best out of them both visually and in terms of performance.
And you might be best off using Sprite Kit, as it has native handling of them. Here's a github repo with a useful thing to make it easier to use rendered bitmaps from a common tool for creating them: https://github.com/tapouillo/BMGlyphLabel
At the moment i can draw a route on a map.
On the map i can zoom and i can pan. If the route is very big it goes really slow.
Therefor i want to do it with OpenGl.
From the map i can convert coordinateToPixel and get the current zoom.
I thought it would be the best to base the translation and zoom on that for the transformation matrix.
I never worked with OpenGL before. I have been reading stuff for the last few hours but most stuff i read is outdated or goes into things i don't care about for now like shaders.
Can someone provide me with resources for simple stuff like on the image?
I never worked with OpenGL before.
You are asking a lot, and I do mean a lot, of work from yourself if you want to switch from using native iOS drawing methods to using an advanced real-time rendering system that you don't even know yet.
I agree with Brad Larson that you are going to go much further and faster by leveraging the tools in iOS for your purpose. However, that does not mean you can't improve performance while using them.
I have found that when using Core Graphics for complicated drawing, you can dramatically reduce the time it takes to render a drawing by drawing it on a background thread. And Apple makes it much much easier to learn and use Grand Central Dispatch than the time it would take you to do all of this in OpenGL.
I learned how to use dispatch queues also for the single purpose of making drawing go faster. The simple technique is to render in the background, then take the results to the main thread for displaying them. Since you already have your drawing code figured out, you won't have to do much extra work to take this extra step, and I think you will be impressed with the performance.
I saw an improvement of at least 5 - 10 times in drawing speed when I implemented Core Graphics drawing with dispatch queues. They are really awesome.
I am adding multiple UIImageView to a UIView to perform operations such as drag,pinch and zoom images.I have added gesture recogniser to all the UIImageViews.Since i'm adding multiple images(UIImageViews) it has brought down the performance of my app.Does any one have a better solution to perform this? Thanks
The adding of many images should not generally, cause enough of a problem that your app would slow down. For example, to illustrate the point with an absurd example, I added 250 (!) image views each with three gestures, and it works fine on an iPad 3, including the animating of the images into their final resting place/size/rotation.
Two observations:
Are you doing anything computationally intensive with your image views? For example:
Simply adding shadows with Quartz 2D has a huge performance impact because it's actually quite computationally expensive. In the unlikely even that you're using layer shadows, you can try using shouldRasterize, which can mitigate the problem, but not solve it. There are other (kludgy) techniques for doing computationally efficient shadows if that's the problem.
Another surprising computationally intensive process is if your images are (for example) PNGs with transparency settings or if you have reduced the alpha/opacity for your views.
What is the resolution/size of the images being loaded? If the images are very large, the image view will render them according to the contentMode, but it can be very slow if you're taking large images and scaling them down. You should use screen resolution images if possible.
These are just a few examples of things that seem so innocuous, but are really quite computationally expensive. If you're doing any Quartz embellishments on your image views, I'd suggest temporarily paring them back and see if you see any changes.
In terms of diagnosing the performance problems yourself, I'd suggest watching the following two WWDC videos:
WWDC 2012 - #211 - Building Concurrent User Interfaces on iOS includes a fairly pragmatic demonstration of Instruments to identify the source of performance problems. This video is clearly focused on one particular solution (the moving of computationally expensive processes into the background and implementing a concurrent UI), which may or may not apply in this case, but I like the Instruments demonstration.
WWDC 2012 - #235 - iOS App Performance: Responsiveness is a more focused discussion on how one measures responsiveness in apps and techniques to address problems. I don't find the instruments tutorial to be quite as good as the prior video, but it does go into more detail.
Hopefully this can get you going. If you are still stumped, you should share some relevant code regarding how the views are being added/configured and what the gestures are doing. Perhaps you can also clarify the nature of the performance problem (e.g. is it in the initial rendition, is it a low frame rate while the gestures take place, etc.).
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.