views:

365

answers:

2

I have a UITableView whose data have sections. I display an overlay view on top of tableView that dims it when searching:

- (UIView *)blackOverlay {
    if (!blackOverlay) {
        blackOverlay = [[UIView alloc] initWithFrame:[self overlayFrame]];
        blackOverlay.alpha = 0.75;
        blackOverlay.backgroundColor = UIColor.blackColor;
        [tableView insertSubview:blackOverlay aboveSubview:self.parentViewController.view];
    }
    return blackOverlay;
}

This works perfectly as long as tableView does not contain sections. When tableView does contain sections and the tableView updates (such as when the view reappears after popping a view off of the navigation controller stack), the section headers are rendered above blackOverlay. This leaves tableView dimmed except for the section headers. I've tried calling [tableView bringSubviewToFront:self.blackOverlay] from within viewWillAppear:, but I get the same behavior.

My current work-around is returning nil for tableView section headers while the overlay is present, but this leaves whitespace gaps in the overlaid tableView where the section headers were previously.

How can I insure that tableView section headers are never drawn above blackOverlay? Or, is it possible to create a view in front of tableView from within a UITableViewController subclass that is not a subview of tableView?

+1  A: 

First off, your function should be tweaked a bit. If you're returning an object that was alloc'd but not autorelease'd, then your method name should indicate that (i.e. newBlackOverlay). Second, your method is modifying a tableView object that was not given to it, so its interactions with other components is not obvious (see Law of Demeter).

The problem is that you're putting this black overlay as a child of the table view. You should be inserting it at the same level of the table view, i.e.:

UIView (set to the view controller's view)
|
+-UITableView
|
+-UIView (your new black overlay)

You can create it inside Interface Builder and set the backgroundColor/alpha properties as you see fit. Create a new UIView @property in your view controller and set it to your new UIView. Then you can change the overlay's alpha value and/or hide it completely in your callback functions for when the user starts/ends searching tasks.

I have a UITableView whose data have sections. I display an overlay view on top of tableView that dims it when searching

FWIW, in case you don't know, you can build search screens fairly easily with the new UISearchDisplayController class Apple introduced in iPhone OS 3.x. Might save you re-inventing the wheel, here.

Shaggy Frog
I should have specified that blackOverlay is actually a lazy-loaded read-only property, so the object is actually managing its memory. Thank you for referring me to the UISearchDisplayController. I was unaware of its existence and indeed it appears that I'm reinventing the wheel!
hadronzoo
FYI, the UISearchDisplayController draws directly on the tableView too if given a TableViewController as its contentsController.
hadronzoo
A: 

I solved this problem by creating a root view controller and making my table view a subview of this controller:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Create the root view to hold the table view and an overlay
    UIView *root = [[UIView alloc] initWithFrame:self.navigationController.view.frame];
    root.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    root.autoresizesSubviews = YES;
    self.view = root;

    // Setup the table view
    UITableView *newTableView = [[UITableView alloc] initWithFrame:self.navigationController.view.frame style:UITableViewStylePlain];
    newTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.tableView = newTableView;
    [newTableView release];
    [root addSubview:self.tableView];

    [root release];
}

I was then able to use a UISearchDisplayController with a search bar at the top of the tableView without issue.

hadronzoo