The way I've done this in the past is to have a content view which houses either an activity view or the view proper.
In the view controller's nib, instead of adding subviews to the main view, leave it empty and create a new view (such as a table view in the example below) for the view proper.
Also create an activity view (with a threaded progress indicator or somesuch) and a "no results" view.
Then derive your controller class from the something like the following:
//
// ContainerViewController.h
//
#import <UIKit/UIKit.h>
@interface ContainerViewController : UIViewController
{
UIView *myContainerView;
UITableView *myTableView;
UIView *mySearchActivityView;
UIView *myZeroResultsView;
UIView *myCurrentlyShowingView;
}
@property (retain, nonatomic) IBOutlet UIView *containerView;
@property (retain, nonatomic) IBOutlet UITableView *tableView;
@property (retain, nonatomic) IBOutlet UIView *searchActivityView;
@property (retain, nonatomic) IBOutlet UIView *zeroResultsView;
@property (assign) UIView *currentlyShowingView;
@end
//
// ContainerViewController.m
//
#import "ContainerViewController.h"
@implementation ContainerViewController
@synthesize containerView = myContainerView;
@synthesize tableView = myTableView;
@synthesize searchActivityView = mySearchActivityView;
@synthesize zeroResultsView = myZeroResultsView;
- (void)dealloc
{
[myContainerView release], myContainerView = nil;
[myTableView release], myTableView = nil;
[mySearchActivityView release], mySearchActivityView = nil;
[myZeroResultsView release], myZeroResultsView = nil;
myCurrentlyShowingView = nil;
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.currentlyShowingView = mySearchActivityView;
mySearchActivityView.backgroundColor = [UIColor clearColor];
myZeroResultsView.backgroundColor = [UIColor clearColor];
}
- (void)setCurrentlyShowingView:(UIView *)view
{
[myCurrentlyShowingView removeFromSuperview];
CGRect frame = view.frame;
frame.size = myContainerView.frame.size;
view.frame = frame;
[myContainerView addSubview:view];
myCurrentlyShowingView = view;
if (view == myTableView)
[myTableView reloadData];
}
- (UIView *)currentlyShowingView
{
return myCurrentlyShowingView;
}
@end
And in the -viewDidLoad method of the derived class, set off the (asynchronous) query:
- (void)viewDidLoad
{
[super viewDidLoad];
myQueryLoader = [[QueryLoader alloc] initWithQuery:@"whatever" delegate:self];
self.currentlyShowingView = mySearchActivityView;
}
and in the delegate callback:
- (void)queryLoader:(QueryLoader *)queryLoader didEndWithResults:(id)results error:(NSError *)error
{
myItems = [results retain];
if (myItems)
self.currentlyShowingView = myTableView;
else
self.currentlyShowingView = myZeroResultsView;
}
Hope this helps!