UIScrollView performance problem because of lots of labels - iphone

I've got a pretty big UIScrollView (contentSize 8000 x 960) with a lot of small labels.
The labels are only added if you scroll to the area where the label belongs to. So, at first, the scrooling is smooth, but as more and more labels are loaded, the performance suffers more and more.
What's the best solution to keep the scrolling smooth? Is CATiledLayer the way to go? Or should the labels off the view should be hidden or something like that?
Thanks a lot for your help!
Stefan
EDIT:
I got a huge performance boost when drawing some objects instead of using views; but now, I've got another problem; if I draw directly onto the UIScrollView, everything performs great. But if I lay a UIView on the UIScrollView and draw on that, performance goes down again (both times calling setNeedsDisplayInRect: in scrollViewDidScroll:).
So hierarchy:
UIWindow
UIView
UIScrollView <== drawing here
works fine.
But hierarchy:
UIWindow
UIView
UIScrollView (size 8000x960)
UIView (size 8000 x 960) <== drawing here
performs bad.
Any ideas why? I need the UIView above because the drawing should be ABOVE some UIViews; so I place the UIViews in the scrollView and draw in the view above...

The label reuse is one of possible solutions. Sometimes it doesn't help a lot. When a new UIView appears the drawRect method will be called and that may cause problems with animation.
Sometimes the best solution is to draw your labels (I mean text) directly using Core Graphics without creating UILabel object or something else. The CALayer will increase performance, but there is a possibility that it will not help you a lot.
But first of all you should remember that views with alpha = 0 or hidden = YES will not be drawn at all, so there is no penalty for using them. Maybe you should try to hide unused ones before using Core Graphics.

The best way would be to have just a few UILabels and reuse them. But you'll have to implement - (void)scrollViewDidScroll:(UIScrollView *)scrollView and do some reusable logic there. Depending on case it might be easier to use a UITableView and transform it 90 degrees, so it looks like a scrollview. That way you can the build-in reusable logic of the TableView.

For others seeing this post, I was able to drastically improve performance and keep UIViews in a scroller without using a table by enabling each view's "shouldRasterize" property. This property renders the view as an image while the view is in motion, causing it to not need to be reprocess for each pixel it moves. So, if I have a UIButton called button, it gets enabled like this:
button.layer.shouldRasterize = YES;

Did u try something similar to UITableViewCell
dequeueReusableCellWithIdentifier
Using a reuseIdentifer to reuse the once allocated labels..

Related

UIScrollView lags when adding UIView with multiple views

I've been working on a Crosswords app for a while and this problem keep returning no mater what i try.
The actual game runs in an UIScrollView because the player should be able to zoom, pan etc.
To the UIScrollview i have added a UIView. First i tried to add multiple UIImageViews and UILabels to the UIView but it resulted in very bad scrolling performance.
Now I've tried to create 3 subclassed UIViews where i wrote a custom drawRect method for each of them. I need 3 UIVIews because only two of the them needs to be redrawn, but not at the same time. The third one contains the clue numbers which are constant.
My UIScrollView hierarchy look like this:
UIScrollView
UIView
UIImageView (show the game board image)
UIView (shows the marked row/column)
UIView (shows the text the user writes)
UIView (shows the clue numbers)
I think the problem is that i have the UIImageView + 3 UIViews in one UIView. When I try to make this hierarchy it doesn't lag, but I'm not able to zoom, pan, scroll etc.:
UIScrollView
UIImageView (show the game board image)
UIView (shows the marked row/column)
UIView (shows the text the user writes)
UIView (shows the clue numbers)
Can you please try do guide me in the right direction. I will appreciate if I do not have to change too much, because the code in the three UIVIews are pretty long.
Thanks in advance :)
EDIT
Screenshot: http://crosswords-plus.com/puzzles/screen.png
First off, I'd recommend shrinking your UIScrollView and pulling the UIView containing the clues out of it. It sounds like it doesn't need to pan/zoom, so you're just adding to the overhead by having it contained inside the UIScrollView.
Secondly, it's hard to give much of an answer without seeing your implementation, but it seems to me that it's possible to turn the UIImageView/UIView/UIView hierarchy into 1 subclass that draws empty, blacked out or filled-in squares plus row/column numbering as necessary. That way, you only have 1 UIView in the UIScrollView and all of this is probably much simpler.
Is that helpful? Is there a reason you're using a UIImageView for the background? Is there a reason you're separating the row/column numbering from the text the user has entered?

UIScrollView lags on iPhone

I'm trying to create a crossword app. The game runs in a UIScrollView, because the player should be able to zoom, scroll etc. The largest crossword are 21x21 which means there need to be 441 touchable tiles. What i've tried so far were to create an UIView and added it as a subView to the UIScrollView. Then I call a method that creates 441 custom UIButtons and set the backgroundImage.
Some of the UIButtons need to have a custom label overlay, so i added a UILabel and set it on top of the UIButton.
When I run the app in simulator all works as it should, but when i test it on an iPhone 4 the UIScrollView lags a lot.
I don't know if this the way to do it? Can you maybe try to guide me in the right direction of how to do this so the UIScrollView won't lag on a device.
Thanks in advance.
Big UIScrollViews are difficult to make smooth without some sort of caching mechanism, such as the one provided by UITableView.
One thing you can do, however, to make life easier for your rendering, is to make sure to use opaque backgrounds whenever possible. In stead of making a view transparent you should make it the same color as its underlying view. This is something that does help.
Also, I have experienced better performance using imageWithContentsOfFile: in stead of imageNamed: for initializing images to be used in a UIScrollView.
In order to not keep all those buttons in memory, you should work with reusable table view cells, this will really improve the scroll performance. Here's one component that could make your life easier: DTGridView, there are also others (you can check Cocoa Controls)

Adding views on top of UIScrollView

When you add a subView to UIScrollView, should this change the smoothness, or anything else for the UIScrollView? For example, if you have a UIScrollView with mainly text, then add a couple of views on top of it in order to add an effect to the text, should this change any of the gestures, or smoothness of the original UIScrollView without the subViews? Thanks.
It won't change the gestures.
As for the smoothness, it depends on how heavy your subviews are. I guess that if you add a lot of them, and they require to render a lot of dynamic content and such, it could make the scrolling a little rough, but if you are adding only a few subviews you should be fine.
As a comparison, think that a UITableView is a UIScrollView with a LOT of subviews on it (each cell is a subview, and cells have several subviews too), and it usually renders fast.
If the sub views you implement have the worst drawRect: implementation in the world, you don't need very many views to get slow, un-smooth scrolling.
You should profile your code in Instruments with the Time Profiler, and see what causes the slow scrolling.

UIView: Rounded Corners Without Performance Issues

I am using an AQGridView to display my data in a grid on iPad. Every cell is a UIView subclass and typically, there are 18 cells displayed simultaneously.
I would like to add a round corner to these cells, so I set the cornerRadius property of the relevant layers (i.e. the layer of the main UIView and of one subview). However, this results in performance issues and the scrolling is not smooth any more. When using other CALayer properties, such as shadowOpacity, this does not happen.
Are there any other ways to add a rounded corner (apart from using an image)? Or am I doing something wrong?
I also saw a major performance hit when using cornerRadius on the layer of a view that contained a UIImageView subview. Rasterization solved that problem: view.layer.shouldRasterize = YES;
It could be where you're placing the setCornerRadius call. Make sure it's somewhere that only gets called once, not, for example, in a drawRect method.

uiview Transition problem

i have a UIview holding two other UIviews. that two subviews having 15 buttons and images. i have to translate the parent view. but the translation is not smooth in 3g phone. im using UIviewanimation and CGAffineTransformTranslate for translating the view. please help me for making it more smoother.
This is a though question to answer in a general way. I have had views that scrolled smoothly suddenly animating jerkily after just a small change. In short, you need to make sure to have as few subviews as possible and have as few non-opaque views as possible (pngs with alpha values translates to non-opaque UIImageViews).
If all else fails, you can render the whole view into an image, switch out the view for the image just before scrolling, and then re-insert the view again after the animation. That way, you are only moving one big and (hopefully) opaque view.
If you have many images make sure they are small-sized, otherwise theyd take up too much memory and there would be nothing to do. To my experience 4-5 large images(740-480) were too much for the phone to handle.