Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISearchController Not Redisplaying Navigation Bar on Rotate

I have implemented the UISearchController and it is working great except...

When I click on the Search Bar the Navigation Bar disappears nicely as expected. When I rotate the phone to landscape view I get this view which makes sense.

enter image description here

However, when I rotate the phone back to portrait view (still selected in search type area) I get this following view.

enter image description here

You can see that the Navigation Bar never reappears. I feel I'm implementing a basic search controller. What could possibly be causing this?

self.venueSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.venueSearchController.searchResultsUpdater = self;
self.venueSearchController.searchBar.delegate = self;
self.venueSearchController.dimsBackgroundDuringPresentation = NO;
self.venueSearchController.hidesNavigationBarDuringPresentation = YES;
self.venueSearchController.searchBar.frame = CGRectMake(self.venueSearchController.searchBar.frame.origin.x, self.venueSearchController.searchBar.frame.origin.y, self.venueSearchController.searchBar.frame.size.width, 44.0);

self.definesPresentationContext = YES;

self.navigationController.navigationBar.translucent = YES;
self.venueSearchController.searchBar.translucent = YES;

self.tableView.tableHeaderView = self.venueSearchController.searchBar;
like image 593
aherrick Avatar asked Feb 17 '15 00:02

aherrick


2 Answers

It looks like the UISearchController forgets to reset the frame of the searchBar when the status bar reappears. I think this is probably a bug in UISearchController; there seem to be a few listed in radar. It seems the searchBar's superview (which is internal to the UISearchController) ends up with the wrong height. This is vexing since the solution therefore involves reaching into the searchController's view hierarchy, which Apple could change... you might want to add a check of the iOS version so it only runs for specified versions.

If you add the code below to your view controller, it will be called when the trait collection changes. It checks to see a) the search controller is active, b) the statusBar is not hidden, and c) the searchBar origin-y is 0, and if so it increases the height of the superview by the height of the statusBar, which moves the searchBar down.

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    let app = UIApplication.sharedApplication()
    if searchController!.active && !app.statusBarHidden && searchController?.searchBar.frame.origin.y == 0 {
        if let container = self.searchController?.searchBar.superview {
            container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + app.statusBarFrame.height)
        }
    }
}

Objective C

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {

    [super traitCollectionDidChange: previousTraitCollection];

    if(self.venueSearchController.active && ![UIApplication sharedApplication].statusBarHidden && self.venueSearchController.searchBar.frame.origin.y == 0)
    {
        UIView *container = self.venueSearchController.searchBar.superview;

        container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height);
    }
}
like image 105
pbasdf Avatar answered Oct 08 '22 22:10

pbasdf


You may need to implement UIBarPositioningDelegate in your view Controller.

self.venueSearchController.searchBar.delegate = self;

The searchBar is looking for a response from it's delegate.

@protocol UISearchBarDelegate <UIBarPositioningDelegate> 

Add the following to your self (I assume it's a ViewController)

#pragma mark - <UIBarPositioningDelegate>

// Make sure NavigationBar is properly top-aligned to Status bar
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
    if (bar == self.venueSearchController.searchBar) {
        return UIBarPositionTopAttached;
    }
    else { // Handle other cases
        return UIBarPositionAny;
    }
}
like image 34
Stephen Furlani Avatar answered Oct 08 '22 21:10

Stephen Furlani