iOS11 UISearchBar missing in UINavigationBar when embedded in UISplitViewController
Asked Answered
S

1

1

Strange things seem to happen when using the new iOS 11 navigationItem.searchController method on a detail view of a UISplitViewController.

The searchBar partly appears as a blank space on the first presentation, then appears in the wrong UITableViewController, but corrects itself after a few push and pops of UITableViewController.

I used to put the searchBar in the tableHeaderView, but I changed the code according to the WWDC recommendation:

if (@available(iOS 11.0, *)) {
    self.navigationItem.searchController = self.searchController;
    self.navigationItem.hidesSearchBarWhenScrolling = NO;
} else {
    self.tableView.tableHeaderView = self.searchController.searchBar;
}

This example is using standard sample code (default project for UISplitViewController and the Apple demo of UISearchController updated for iOS 11 (using a single UITableViewController)).

The initial view containing the searchController looks like this:

enter image description here

And clicking a UITableView item yields this:

enter image description here

However after clicking on a UITableView item and returning twice - it looks as it should:

enter image description here

and:

enter image description here

I was trying to determine why the Apple example for UISearchController worked and my code didn't. The main difference was it was embedded in UISplitViewController in the Detail View. Which means if shown in Compact mode has an extra UINavigationController in the stack. I found if my seque avoided the extra UINavigationController - it works correctly (but breaks device rotation). Similarly change the segue to modal allows it to work.

enter image description here

I note this is similar to this old question: UISplitViewController with new UISearchController issue with UISearchBar

I have created a sample project that demonstrates the problem (sample code: searchControllerDemo)

I'm stumped as to what is going on. So any help would be very much appreciated.

Striction answered 24/9, 2017 at 6:12 Comment(10)
I am also experiencing trouble with the detail view controller when showing large title through prefersLargeTitles. On iPhone: A blank space appears in the detail view controller in place of the large title. Upon scrolling the table view upward the title appears normally in the regular size as in iOS 10... On iPad: Everything works like a charm. I played around with the Master-Detail app template and everything seems to be working perfectly on both devices, the large titles search controllerLegionary
Yes - the problems seem to only occur with the compact (iPhone) size class. iPad works fine. My only reason for trying navigationItem.searchController is because it is meant to resolve the iPhone X landscape issues. I'm thinking of disabling iPhone landscape modes in my app as a solution. Life is too short.Striction
OK, I solved the issue with the large title, maybe this will help you with the UISearchBar somehow... I actually want to embed one myself in the detail view controller too but will look into this later... There is a lot complexity with the UISplitViewController. I have included a call to a function that sets up the view (incl. large titles) to a calculated property in the detail view controller. So Upon setting this property in the master view controller, the view is setup correctly with the large title. The view setup function still gets recalled again in the viewDidLoadLegionary
Hi Michael - Have you reached a solution to this? I'm fighting against the same thing now with no luck!Legionary
Are you getting this printed in the console when the detail view controller first appears? +[CATransaction synchronize] called within transaction Legionary
@AhmedAbdelHadyKhedr - no I don't see those [CATransaction synchronize] messages.Striction
I think we need to find a way to initialize the UISearchController in the detail view controller inside prepareForSegue in the master view controller. On the iPad, both master and detail VCs are loaded together hence no problems, same for landscape on iPhone wide screens.Legionary
I am trying to make the previous method (embedded in tableHeaderView) work instead of battling with this approach: using uisearchcontroller with uisearchbar in tableheaderview in ios11.Striction
I tried this. For iOS 11, it wrecks the table view layout. The first row gets partially hidden under the search bar unlike in iOS 10Legionary
Anyway I filed a bug report to Apple, let’s see their response!Legionary
L
2

It's been a while since this erupted but thought to leave a note here for whoever will face the same issue...

On compact width devices, upon segueing from master to detail, the detail navigation controller is on top of the master view controller, unlike regular width where the two navigation controllers have their own separate root view controllers.

So, the UINavigationController of the detail view controller needs to be removed upon segue in combact width devices using UISplitViewControllerDelegate method: splitViewController(_:showDetail:sender:)

func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
    if splitViewController.isCollapsed, let navController = vc as? UINavigationController {
        if let detailVC = navController.topViewController {
            splitViewController.showDetailViewController(detailVC, sender: sender)
            return true
        }
    }
    return false
}
Legionary answered 1/5, 2018 at 17:50 Comment(1)
Issue still happens on iOS 12 with Xcode 10, your solution save my work.Trill

© 2022 - 2024 — McMap. All rights reserved.