Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

searchBar missing from view hierarchy in iOS 12

I have a UISearchController with searchBar assigned to my view controller's navigation item. All works fine in iOS 13.3. However, in iOS 12.4, the searchBar is missing and appears not have been added to the view hierarchy.

Here is the UI in iOS 13.3:

enter image description here

Here is the same in iOS 12.4:

enter image description here

My code to configure the search controller is as follows:

self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.obscuresBackgroundDuringPresentation = NO;

NSString *placeholder = NSLocalizedString(@"Address or place name", nil);

self.searchController.searchBar.placeholder = placeholder;
self.searchController.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.searchController.searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
self.searchController.searchBar.delegate = self;

self.definesPresentationContext = YES;

self.navigationItem.hidesSearchBarWhenScrolling = NO;
self.navigationItem.searchController = self.searchController;

[self.searchController.searchBar sizeToFit];

If I check the view hierarchy for the searchBar by entering this in debugger:

po self.navigationItem.searchController.searchBar.superview.superview

I see the following in iOS 13.3:

<UILayoutContainerView: 0x7f8c97b300c0; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x60000373dd40>; layer = <CALayer: 0x6000038ae620>>

and this in iOS 12.4:

nil

I'm using Xcode Version 11.3.1 (11C504), and the project targets iOS 12.0. The view controller is loaded from a storyboard and is configured as detail view controller of a UISplitViewController.

What should I be doing differently to get the searchBar to appear as expected in iOS 12?

like image 249
stephent Avatar asked Jan 23 '20 18:01

stephent


2 Answers

This actually because of iOS 12 problem with UISearchController initializer which takes nibName and nibBundle as its parameters and if you do not override it in your custom UISearchController class you will face problems like above. I simply mange to resolve this issue by implementing this snippet in my UISearchController class:

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}

If you don't want to subclass UISearchController you should implement above initializer instead of:

UISearchController(searchResultsController: nil)
like image 71
Alireza Alemi Avatar answered Nov 15 '22 22:11

Alireza Alemi


No explanation found for the behaviour described in the question, but I was able to work around the problem by applying the iOS 10 fallback behaviour to iOS 12:

if (@available(iOS 13, *)) {
    // For iOS 11 and later, place the search bar in the navigation bar.
    self.navigationItem.searchController = self.searchController;

    // Make the search bar always visible.
    self.navigationItem.hidesSearchBarWhenScrolling = NO;
} else {
    // For iOS 10 and earlier, place the search controller's search bar in the table view's header.
    self.tableView.tableHeaderView = self.searchController.searchBar;
}

(This seems just about acceptable: as iOS 12 ages out of the installed base, the proportion of users seeing the fallback version will continue to decline - it's already <15% at 6 months post iOS 13 release for my app.)

like image 2
stephent Avatar answered Nov 16 '22 00:11

stephent