UITableViewController background image with UINavigationController

Veröffentlicht am 19. April 2012 in: Neues über Apps und mobile Weblösungen

The title is not complete but I have to keep it tight for Google…

My case

My problem was that I have detail views for my UITableViewCells and without a UINavigationController you can’t push them or get back to the table. While I have a tabbar navigation in my app I have to initialize a UINavigationController programmatically and set the UITableViewController as the root controller.

But this is a problem if you want to set a background image which is static behind the table. You can’t set a background image behind a UITableViewController in the Interface builder so you have to add them programmatically, too. This challenge is a bit weird, because if you try to add them on the current view controller it will fail.

What you have to do is to get the navigation controller which is the parent view controller. You should prefer to add the subview before the table view is shown to the user. To save some performance, check if a UIImageView is already present so that you don’t need to load and push the same image again.

The magic

- (void)viewDidAppear:(BOOL)animated
{
    NSArray *subViews = [self.parentViewController.view subviews];
    if ([[[[subViews objectAtIndex:0] subviews] objectAtIndex:0] class] != @"UIImageView") {
        UIImageView *backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Apple_background"]];
        backgroundImageView.frame = [[UIScreen mainScreen] applicationFrame];
        [[subViews objectAtIndex:0] addSubview:backgroundImageView];
        [[subViews objectAtIndex:0] sendSubviewToBack:backgroundImageView];
    }
    [super viewDidAppear:animated];
}

At first we load the subviews array of the parent view, which is our navigation controller. If the UIImageView is not already present we load our image with our application frame rect.
This prevents having to add the view to an area where content could be already present (e.g. top status bar, or navigation bars). After we modified our image we add the subview to the navigation controller and send them to the back. This is pretty easy but before you can see anything, you have to make your table transparent. You do this by checking the opuaqe flag in the interface builder for your UITableView. Sometimes the table cells don’t get transparent, in this case just click again on the table view and set the background color to default. Do it again if the color is already on default. It’s a bug in Xcode 4.2.

For a better ui navigation your UINavigationController should hide its navigation bar. This saves some space but don’t forget to show the navigation bar if you push your detail view!
I prefer the viewWillAppear function within the detail view controller. If the user returns to the table view the same function in the UITableViewController should hide the bar again.

To display the navigation bar:

// MyDetailViewController.m
- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController setNavigationBarHidden:YES];
    [super viewWillAppear:animated];
}

To hide the navigation bar:

// MyBackgroundTableViewController.m
- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController setNavigationBarHidden:YES];
    [super viewWillAppear:animated];
}

Download

You can download my example project on GitHub: https://github.com/LifestreamCreations/tabNavBackground

Hopefully this is useful for someone else!

Beitrag teilen

Kommentare