views:

1781

answers:

4

I can't seem to get a UISearchBar to position itself from the far left to the far right in the navigation bar. In the -(void)viewDidLoad method, I have the following code:

`UISearchBar *sb = [[UISearchBar alloc] initWithFrame:self.tableView.tableHeaderView.frame];
sb.delegate = self;
self.navigationItem.titleView = sb;
[sb sizeToFit];
[sb release];`

When you build and run, it looks just fine at first glance. However, looking more closely, you can tell there is a margin/space on the left. This wouldn't be a big deal in the grand scheme of things, but when I tap the search bar to start a search, I animate the cancel button into view. Because the search bar is positioned slightly to the right, the animation is jerky and the cancel button falls off the end like so: link text

It seems as if the UINavigationItem is like a table with three cells, where there is a padding on the first and last which I can't remove - nor does there seem to be a way to 'merge' it all together and then place the search bar there. I know this look is possible, because the AppStore search has a search bar in the navigation bar and it goes all the way to the edges. Anyone know how to get the search bar to go all the way to the edges so my slide-in cancel button animation will work properly?

A: 

Maybe apple is using an UISearchDisplayController for doing these kinda things. This one is alligned left. Sample Image

caahab
I tried the UISearchDisplayController. However, that 'control' puts the search bar in the table header (when not searching), not the nav bar. Then when you tap on the search bar, it animates and moves up to the nav bar, similar to the Contacts search. I don't like that. I want it to look just like the AppStore search, where the search bar REMAINS in the nav bar, regardless if you're currently searching or not. Is that possible at all?
tbehunin
Taken from the iPhone SDK "The navigation bar displays a back button on the left and the title in the center by default. You can change this behavior by specifying either a custom left, center, or right view." so maybe you can experiment with left and center view. Is it necessary that you have a real NavigationBar or is it just the look of it?
caahab
I experimented with a custom left and center view, but still didn't look like the AppStore search.I got it to look like a navigation bar, by hiding the real navigation bar and putting the search on the table view's header. That worked perfectly. The only problem with that is that now the header having the searchbar scrolls with the screen. I want it to be stationary like a navigation bar is. Any other ideas? I simply want a search to look like the AppStore search. I can't believe it's that hard to do. :(
tbehunin
I think that Apple tweaked the UISearchDisplayController to get the search bar to REMAIN in the navigation bar somehow. How they did it remains a mystery.
tbehunin
+1  A: 

Actually, there's a really simple solution. All you have to do is create a zero-width view for the back item:

UIView *hackView = [[UIView alloc] initWithFrame:CGRectZero];
UIBarButtonItem *hackItem = [[UIBarButtonItem alloc] initWithCustomView:hackView];      
self.navigationItem.backBarButtonItem = hackItem;
[hackView release];
[hackItem release];

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
[searchBar sizeToFit];
self.navigationItem.titleView = searchBar;
[searchBar release];

Be sure to do this in your loadView method, not init. I'm not sure why that makes a difference, but it does.

Apparently it's about timing. Having it in loadView stopped working for me, but putting it in viewWillAppear works (with a check so that it's only done once, of course). I think the idea is to set the titleView after some initialization has already completed.

Hilton Campbell
A: 

I think I found out the answer - though I haven't tested to verify. In the issue I provided above, I have the following structure:

tab bar controller -> navigation controller -> view controller(s)

The search bar in question was in a view controller, which in turn was in the navigation controller, which navigation controller is in the tab bar.

I was casually watching the Stanford CS 193P (Spring 2009) courses and at the end of Lecture 13, the answer may have been presented. Alan Cannistraro stated that the structure of the Presence app should have this structure:

this structure

where the bottom view controller (adjacent to the tab bar controller) was the view controller which had the search bar control. He warned if it's not done in this fashion, you'll "run into problems". Possibly the problem I faced? I believe so.

tbehunin
A: 

The following code hides the navigationBar just for this UIViewController:

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

- (void)viewWillDisappear:(BOOL)animated
{
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

So to get the UISearchBar to show in the UINavigationBar's place, on your root view controller just have your search bar where the navigation bar would be normally!

spiderlama