2
votes

I am developing an iPhone app, and I am subclassing UINavigationBar to create my custom navigation bar. What I want is a taller navigation bar, and a UISearchBar to be in the titleView. I want more space in my nav bar because I want to put a segmented control at the bottom, under the search bar. Here is what I have done so far:

// Custom navigation bar implementation

const CGFloat BUNavigationBarHeightIncrease = 38.0f;

@implementation BUNavigationBar

// This resizes the navigation bar height
- (CGSize)sizeThatFits:(CGSize)size {

    CGSize amendedSize = [super sizeThatFits:size];
    amendedSize.height += BUNavigationBarHeightIncrease;

    return amendedSize;
}

// This repositions the navigation buttons 
- (void)layoutSubviews {
    [super layoutSubviews];

    NSArray *classNamesToReposition = @[@"UINavigationButton"];

    for (UIView *view in [self subviews]) {

        if ([classNamesToReposition containsObject:NSStringFromClass([view class])]) {

            CGRect frame = [view frame];
            frame.origin.y -= BUNavigationBarHeightIncrease;

            [view setFrame:frame];
        }
    }
}

@end

I am assigning this nav bar to a navigation controller like this:

- (IBAction)searchButton:(id)sender {
    SearchViewController *searchViewController = [[SearchViewController alloc] init];
    UINavigationController *searchNavigationController = [[UINavigationController alloc] initWithNavigationBarClass:[BUNavigationBar class] toolbarClass:nil];
    [searchNavigationController setViewControllers:[NSArray arrayWithObjects:searchViewController, nil]];

    [self presentViewController:searchNavigationController animated:YES completion:nil];
}

and in the SearchViewController's viewDidLoad, I have this:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.searchBar = [[UISearchBar alloc] init];
    self.cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(cancelButton:)];

    [self.searchBar setSearchBarStyle:UISearchBarStyleMinimal];
    [self.searchBar setPlaceholder:@"Search"];

    // For debugging purposes
    [self.searchBar setBackgroundColor:[UIColor greenColor]];

    [self.navigationItem setTitleView:self.searchBar];
    [self.navigationItem setRightBarButtonItem:self.cancelButton];
}

And here is what the screen looks like after all this: Simulator screenshot

The search bar is in the middle, and the frame has been stretched to fill the entire nav bar (shown in green). Instead what I want is for the search bar to stay at the default height, and be moved up to the top of the nav bar. How can I achieve this?

1

1 Answers

5
votes

Just call below function in viewDidLoad

 - (void)CustomizeNavigationBarForSearch
{
    self.navigationItem.leftBarButtonItem = nil;
    self.navigationItem.rightBarButtonItem = nil;

    self.navigationController.navigationBar.translucent = YES;
    self.navigationItem.hidesBackButton = YES;

    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"ImgNavBarBG"] forBarMetrics:UIBarMetricsDefault];

    //Menu
    UIButton *btnMenu = [UIButton buttonWithType:UIButtonTypeCustom];
    [btnMenu setFrame:CGRectMake(-5, 5, 35, 35)];
    [btnMenu setImage:[UIImage imageNamed:@"BtnMenuDrawer"] forState:UIControlStateNormal];
    [btnMenu setImage:[UIImage imageNamed: isMain ? @"BtnMenuDrawer" : @"BtnBack"] forState:UIControlStateNormal];
    [btnMenu addTarget:self action:isMain ? @selector(clickOnMenu:) : @selector(clickOnBack:) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *fixedspace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    fixedspace.width = -12.0f;
    UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc] initWithCustomView:btnMenu];
    self.navigationItem.leftBarButtonItems = @[fixedspace, leftBarButton];

    //Search
    searchPlayer = [[UISearchBar alloc] initWithFrame:CGRectMake(30, 2, SCREEN_WIDTH - 80 - 30, 30)];
    searchPlayer.placeholder = @"Search";
    searchPlayer.showsCancelButton = NO;
    searchPlayer.delegate = self;

    searchPlayer.searchBarStyle = UISearchBarStyleMinimal;

    searchPlayer.barTintColor = [UIColor clearColor];
    [searchPlayer setAutocapitalizationType:UITextAutocapitalizationTypeNone];
    [searchPlayer sizeToFit];


    //Search Text field customization
    [UITextField appearanceWhenContainedIn:[UISearchBar class], nil].backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.5];
    [UITextField appearanceWhenContainedIn:[UISearchBar class], nil].textColor = [UIColor whiteColor];
    [UITextField appearanceWhenContainedIn:[UISearchBar class], nil].font = THEME_FONT_BOLD(15.0);
    [[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setDefaultTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];

    id barButtonAppearanceInSearchBar = [UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil];
    [barButtonAppearanceInSearchBar setTitleTextAttributes:@{NSFontAttributeName:THEME_FONT(15.0),
                                                         NSForegroundColorAttributeName : [UIColor whiteColor]
                                                         } forState:UIControlStateNormal];
    [barButtonAppearanceInSearchBar setTitle:@"Cancel"];

    [searchPlayer setValue:[UIColor lightGrayColor] forKeyPath:@"_searchField._placeholderLabel.textColor"];

    self.navigationItem.titleView = searchPlayer;
}