tags:

views:

626

answers:

2

How do I create a loading screen that can be reused at any given time. I'm aware of the Default.png but I need the flexibility to plug in a loading screen at any point during the application life cycle.

This is what I have thus far.

//inside a method that gets called by a UIButton

LoadingViewController* loadController = [[LoadingViewController alloc] initWithNibName:@"Loading" bundle:nil vertical:NO];
[self.view addSubview: loadController.view];

//some method call that takes a few seconds to execute
[self doSomething];

//This loads some other view, my final view
[self.view addSubview: someOtherView]

but it seems that the loading view is never displayed. Instead the previous view stays there until the "someOtherView" gets added. I put trace logs and the code does seem to get executed, I even replaced [self doSomething] with a sleep(2), but the intermediate loading view is never displayed.

If I remove [self.view addSubview:someOtherView]; then after a few seconds...(after doSomething finishes executing) the load view is displayed since there is no view that is pushed on top of it, however this is obviously not the functionality I want.

Can explain this behavior? Is there something about the rendering cycle that I am misunderstanding because it doesn't seem like the view (on the screen at least) is instantly updated, even though I call a [self.view addSubview: loadController.view];

Would I need to create a separate thread?

+1  A: 

I created a subclass of UIView where I initialized how my loading-view should work and look like. (My view appeared and slided in from the bottom with an nice animation).

I then added code that handled whether the loading-view should be visible or not in a subclass of UIViewController.

I then let all my viewcontrollers be an subclass of my new viewcontrollerclass which made it possible for me to do:

[self showloadingMessage:@"loading..."];

in all my viewcontrollers...

ullmark
+3  A: 

In general, for changes in the UI to be made visible to the user, control must return to the main runLoop. You are only returning to the runLoop after taking the loading view down and replacing it with the other view. One strategy for dealing with this is to move the code that does the loading onto another thread. NSOperation and NSOperationQueue can be used for this.

An even simpler approach is to use performSelectorInBackground:withObject to do the processing. Once processing is complete the UI can be updated again to show the data. It is important to remember that the UI updates must be carried out on the main thread. Use performSelectorOnMainThread:withObject:waitUntilDone: to accomplish this from the loading thread.

This sounds like a lot of complication but it is really as simple as breaking your single method up into three separate methods as follows:

  • Display the loading view and start the background process - this is the button action method.
  • Do the background loading - called from the button action function with performSelectorInBackground:withObject.
  • Remove the loading view and update the display with the data - called from the background thread with performSelectorOnMainThread:withObject:waitUntilDone.
m4rkk