large amount of small objects in UISCrollView
We've got the following problem. We need to display ScrollView content, consisting of a large amount of small objects (guitar tablature and notes) like shown on this screenshot http://www.iphones.ru/forum/index.php?app=core&module=attach§ion=attach&attach_rel_module=post&attach_id=38991. The content itself can be considerably big (contentSize.width>60000), with the corresponding number of objects. The screen can theoretically fit up to one hundred of objects, with the objects being pretty small (notes, figures).
We tried to do it with all the available objects - UIImageView, UILabel. If we try to place them all simultaniously at scrollView, the app gets terribly slow and crashes with lack of memory. If we add them upon necessity and remove, when they are invisible, then there is only the problem with slow performance.
Decided to look at how it is solved in some top apps with a 开发者_Python百科similar functionality - got source code of the .h files of TabToolkit (on the screenshot) using class-dump-z.
They use methods of these types:
- (void)drawSignatureNumber:(unsigned char)arg1 inContext:(struct CGContext *)arg2;
- (void)drawMeasureNumber:(struct CGContext *)arg1;
- (void)drawRepeatNumber:(struct CGContext *)arg1;
Turns out, that we should look toward Quartz2d and Core Graphics? Or is there any other solution to the problem?
Whilst I'm somewhat reluctant to help you out since you've openly admitted trying to lift another developers source code from their competing product, I do recommend you take a look at CATiledLayer as it will allow you to draw huge areas on screen with little performance degradation.
What we've done in similar situations (in quite a number of apps in fact), is use a scroller with say 5 'pages' (i.e. 5x the visible content width), and load the content dynamically. I assume this is what you meant when you said "If we add them upon necessity and remove, when they are invisible". This has not slowed performance as I've seen it, as long as view unloading is done with a good focus on memory management.
i.e. (say we're using 5 pages)
- Load 5 pages initially into the scroller upon loading
- When the user swipes left, if there is more content to be loaded on the left, remove the rightmost page from the scroller, move the remaining pages to the right by one, and add a new page to the left. Ditto if the user swipes right.
- If there's no more content to be loaded on one end, leave it as it is, and the scroller would bounce at the end as needed.
Apologies if I'm repeating the method you've already used, but just stating this again, cos by experience, this has worked out very well for us in many high end apps with both very long scrollers or even circular scrollers, and gives us a good degree of customizability.
Hope this helps.
What first came to my mind was using NSOperation
(Threading) since this is an intensive operation.
Also make sure you use the right method to load your images depending if you want to cache your image or not.
+ (UIImage *)imageNamed:(NSString *)name
Here images will be cached and shouldn't be used if you load many images at once.
+ (UIImage *)imageWithContentsOfFile:(NSString *)path
- (id)initWithContentsOfFile:(NSString *)path
You should choose one of these two methods to load your images if you don't want the images to be cached. Use it for images which are not used immediately. e.G. the images which are not on screen at the very first load.
I recommend you to take a look at the Effective iPhone App Development - Part 2 video. Starting at minute 14' or 18' it will discuss the mentioned issues.
Not sure if these are topics you were already concerning about but I thought it's worth to mention them.
精彩评论