I have a pretty standard setup of UITableview
as master controller in UISplitviewController
, universal iOS9
app.
Again, standard fare, I inserted a UISearchBar
as the header of the table.
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.hidesNavigationBarDuringPresentation = NO;
[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
No need for showing the rest of my code, the search and all work as expected, on the iPhone
. My issue is that the search bar does not ever receive focus or present the keyboard when run on iPad
. No response, seems not to receive touches. Does not even respond to programmatically attempting to becomeFirstResponder
.
Nothing happens.
The search bar is visible and placed appropriately, there are no underlay or overlay issues.
It works fine on iPhone
. Receives touch, presents keyboard, search works. Presumably there is a critical difference in presentation when UISplitviewController
is collapsed. With hours of search, pouring through the documentation and every tutorial I come across, I have not found a similar experience which is surprising.
Additional note: If I use multi tasking to shrink the split view to collapsed on iPad, the search bar then works, same as on iPhone
. It definitely has to do with the collapsed state of the split view.
UPDATE: (Getting closer)
After further experimentation I find that the search bar works on the iPad if you start the app in landscape. In portrait mode, my primary controller is hidden. It slides in by selection of the displayModeButtonItem
, which is set to the leftBarButtonItem
of the detail controller. That is when the searchBar breaks and no longer will respond to touches.
If I start in landscape, then rotate to portrait, it stops working as well. Rotating back to landscape does not fix it. Once broke, it stays broke until a restart.
I tried moving definesPresentationContext
to the viewWillAppear
method of the master controller, but that had no effect.
Further Update:
Another unexpected circumstance is that there is no problem with the search bar at all on iPhone 6plus. Works regardless of orientation, collapsed or no and doesn't matter which state it starts in. I would expect this would be same as iPad when in landscape orientation. Works completely on iPhone
.
I still have not figured this out. My latest attempt to fix, I moved all the search controller initialization to the viewDidLayoutSubviews
method. No change whatsoever.
Also, I noticed that when the search is active, keyboard onscreen, if I rotate the iPad the keyboard goes away but the search bar remains active. I didn't realize at first, then I saw the cancel button still displayed. It won't receive touches and does not have keyboard, but it is apparently still first responder.
Sample Project Uploaded to GitHub: Github Repository
NOTE- There was no issue until I added my UISplitview Delegate methods to the project. I wanted to add this to my question right away, so, I haven't yet even tried to see exactly how these delegate methods affect the search bar but obviously the issue is created there somewhere.
Update:
I tried a few more variations with no success.
- Move search bar to section header. No joy.
- Put search bar in a UIView as a content view. No joy.
- Remove search bar on disappear, reinsert on did appear. No joy.
- Manipulate the size of search bar frame to ensure it is not clipped. No joy.
I also looked at the view hierarchy in profiler, the search bar is top level, not covered by anything else.
Final Wrap:
@tomSwift workaround did correct my issue on iPad. On further testing, I found it broke my iPhone UI. Presumably, this is more an issue with my own setup and the timing of creation of the Master/Detail View Controllers. It would seem some important objects no longer were created in time as perhaps the detail view controller didn't exist yet. I poked around to fix by moving critical items into App Delegate but that became unwieldy and I couldn't easily narrow it down, so I hacked a fix with:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
}
A more elegant solution is likely to be had, but this has taken enough of my time. Everything works now. Radar filed- 28304096