Microsoft Outlook used to have – and maybe still does – a scrolling timeline view of all activity that has taken place within outlook. I’d like to recreate something like that in my app.
I have studied the documentation for UIScrollView, and I know how to make it work the way I want. My question is more geared towards to most efficient way to present several hundred items in a UIScrollView when the content view is likely to be large.
I could:
- Assemble a list of smaller views, each representing a day, for example, and populate those smaller views with the data items from each of those days and then append those aggregate views as sub views into the content view.
or
- I could just simply populate a content view with sub views for each of the data items I want to display on the timeline.
What I’m looking to find out is:
- What’s the most efficient way, from a memory and time perspective, to present all these data points? Each will appear on the timeline as a label or button.
- Which method would more naturally support pinching and zooming?
- Is it better to initialize the entire content view ahead of time (and possibly take a big time penalty), or is it better to just initialize the view in the vicinity of the ‘view window’ and then add in details as the user scrolls around?
Thanks!
The only way you’ll know for sure is by experimenting a bit. I realise that’s not an overly helpful answer, but I can at least give you some hints:
Efficiently displaying more than one screenful of stuff with
UIScrollViews is notoriously difficult. I’ve struggled with this for weeks in some cases. This was much worse on older hardware (iPhone 3G/2nd gen iPod or older) but you can still easily bring modern iOS devices to a crawl if you get it wrong. You will typically run into two performance issues:UIViews (this includes UILabel etc.) on screen at once severely hurts performance. You’ll run into this if every data point is a view and you can zoom out to see all of them.You can probably see how this fits badly with zooming: you don’t know exactly how much one screenful is!
shouldRasterizeproperty to true on theirCALayer. This should essentially pre-render all the subviews of a tiles into a texture, so when it comes to rendering the screen, it’ll use that pre-rendered image instead of walking through all your subviews and rendering them individually. Make sure to disable it again once the user zooms in again sufficiently. Also try to avoid setting it for all tiles at once or it will stutter, so for example you could set up separate random zoom level thresholds for each tile.If you end up having trouble with
shouldRasterize, you may need to work at theCALayerlevel directly. If none of this helps, the sledgehammer method is to useCATiledLayerlike theMKMapViewand others do. This requires you to do all the rendering and touch event handling yourself, and will normally also cause the (somewhat ugly) fade-in you get when scrolling in the Maps and Safari apps.Some additional hints:
UIImages if you can. If each view is slightly different, generate the images on-demand in drawRect: or using filters rather than drawing them asCGImages up front, or loading them from file.I hope that helps you get started. Good luck!