I am displaying lots of UIViews in a root UIView. (I know it's not a good practice). The sub views include UIImageViews, UILabels and custom UIViews using Quartz drawing some lines. After generating all the views, I add the root view to a UISCrollView to display them. The problem is, all the images are displayed instantly, but the text in the labels and the lines I draw in the drawRect method will take a long time to display. If I zoom the scroll view, all of them will display instantly. What's the problem? Thanks.
2 Answers
Hard to say without seeing your code, but sounds like something is up with your app. iOS can handle a large number of subviews without choking or stuttering. And all the UIView
stuff is single-threaded -- in fact, to my knowledge, all rendering happens in the same run loop (CATiledLayer
-backed views being the only exception I can think of). So even if rendering was getting bogged down, I would expect a long pause and then everything displayed at once. Not the piecemeal result you describe.
Are you adding views programmatically, or from nib? Is everything in the same nib, or are some things in their own, separate nib? What's your UIViewController
situation look like?
Try popping some logging in the things that are displaying late. Are their -drawRect:
s really getting called late, or are they getting called with everything else and they are obscured by something else? Try starting a new, clean app with nothing in it and drop each of your subviews in there to see how they perform in isolation? Pay particular attention to anyplace you're using GCD, threading, or preform:AfterDelay:
type calls.
If all that fails, post as sample project so we can actually debug what you've done.
Had a similar problem where my label wasn't appearing for like 10+ seconds even though the view containing the label was appearing right away. The reason was because I was doing it in a closure on success of an asynchronous API call. I'm not too familiar with how iOS UI works, but for whatever reason you can only make UI changes on the main thread.
Putting my UI/View related code within:
DispatchQueue.main.async {
//View related code
}
immediately solved my problem.