Reputation: 1434
The structure:
View1 (click a button) -> present modally (MyModalView: UITableViewController)
MyModalView has UISearchController embedded. The searchBar of UISearchController is placed in MyModalView.tableView.tableHeaderView.
It's been working fine since iOS 8.0. However on iOS 9, the searchBar disappear when the UISearchController is active. Please take a look at theses pictures below
UISearchController active on iOS 8:
UISearchController active on iOS 9:
The very standard code:
override func viewDidLoad() {
super.viewDidLoad()
// Dynamically create a search controller using anonymous function
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
// Auto sizing row & cell height
self.tableView.estimatedRowHeight = 130
self.tableView.rowHeight = UITableViewAutomaticDimension
self.definesPresentationContext = true
// No footer for better presentation
self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}
This issue also happens in iOS 9.1 beta...
Any idea / pointer would be deeply appreciated
Cheers.
Upvotes: 55
Views: 31765
Reputation: 1142
None of them worked for me, I fixed it using this hack
func position(for bar: UIBarPositioning) -> UIBarPosition {
if UIDevice.current.userInterfaceIdiom == .pad {
return .top
} else {
if iOSVersion <= 9 {
return .top
}
return .topAttached
}
}
Upvotes: 0
Reputation: 434
sc.hidesNavigationBarDuringPresentation = false
does the trick for me
lazy var searchController:UISearchController = {
let sc = UISearchController(searchResultsController: nil)
sc.searchResultsUpdater = self
sc.obscuresBackgroundDuringPresentation = false
sc.searchBar.placeholder = "Search"
sc.hidesNavigationBarDuringPresentation = false
return sc
}()
Upvotes: 0
Reputation: 450
I had the same problem, and when I debugged the UI on Xcode I found that the UISearchBar
view was moved to another view and the width was zeroed.
I fixed it by setting definesPresentationContext
property of the UISearchController
to false
, and setting it true
for the containing UITableViewController
.
I added only one line to your viewDidLoad()
.
override func viewDidLoad() {
super.viewDidLoad()
// Dynamically create a search controller using anonymous function
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.definesPresentationContext = false // Disable the presentation controller
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
// Auto sizing row & cell height
self.tableView.estimatedRowHeight = 130
self.tableView.rowHeight = UITableViewAutomaticDimension
self.definesPresentationContext = true // This one remains the same
// No footer for better presentation
self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}
Upvotes: 3
Reputation: 1434
It seems all of us got the same problem but they were solved in different ways. However none of the suggested answers worked for me :(. Nevertheless thank you all for your time.
I got a solution that solved my problem. It is setting Extend Edges - Under Opaque Bars of my (MyModalView: UITableViewController) to true in the Storyboard using Interface Builder.
In summary:
MyModalView: UITableViewController, in Storyboard using Interface Builder has
Extend Edges: - Under Top Bars ticked - Under Bottom Bars ticked - Under Opaque Bars ticked
Upvotes: 66
Reputation: 483
It works
override func viewDidLoad() {
super.viewDidLoad()
self.extendedLayoutIncludesOpaqueBars = !self.navigationController!.navigationBar.translucent
}
Upvotes: 1
Reputation: 3500
I had to
self.aNavigationController?.extendedLayoutIncludesOpaqueBars = true
I found a similar question here but in my case it was not on the viewDidLoad method. I had to try different views until it worked. Now I can have both a custom navigation bar color and the search bar,
Upvotes: 19
Reputation: 2457
I don't have a navigation bar in this place of an app. None of other SO posts helped me, so I've fixed it this way:
- (void)layoutSubviews
{
[[[self searchController] searchBar] sizeToFit];
}
Upvotes: 2
Reputation: 6933
If you want to hide you navigation bar, and present search controller full screen, set the following on your navigation bar and search bar won't dissapper:
navigationController?.navigationBar.translucent = true
Upvotes: 0
Reputation: 231
Thanks @wiles duan and @Techprimate
In my case, I fixed this issue by setting:
self.definesPresentationContext = NO;
And implement the following 2 methods in UISearchControllerDelegate
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
Upvotes: 10
Reputation: 61
Setting the navigationBar permanently to translucent in storyboard solved my problem.
Upvotes: 1
Reputation: 1142
I'm not sure what exactly is the problem but I 'fixed' it by:
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.definesPresentationContext = NO;
My guess is that UISearchController
is doing something funky when it is trying to present as a navigation bar. So, this is a hack but it at least doesn't block the user. The search bar doesn't do the cool animation and cover up the navigation bar.
Upvotes: 70
Reputation: 1066
I found it's the simulated metrics (top bar) in storyboard that's cause this problem. In my case, the following lines work, but I still don't know why.
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
}
Upvotes: 36
Reputation: 1069
I fixed it in my case by removing
definesPresentationContext = true
I didn't test yet if there are any disadvantages of removing this!
Upvotes: 6