Swift ios11 NavigationItem SearchBar won't hide completely - ios

Having an issue with adding a search controller to a navigationItem in iOS11 / Swift 4.
Basically everything works as expected for the most part, pull down will reveal the search bar and searching works fine. However when trying to hide the search bar by scroll back up... the bar won't hide completely and remains as a thin strip (see below).
I have declared my search controller as follows:
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.scopeButtonTitles = ["All", "Samples"]
searchController.searchBar.delegate = self
navigationItem.searchController = searchController
Before (scroll down to reveal search bar):
After (scroll up to hide):

As discussed in this Apple forums thread.
When the value of this hidesSearchBarWhenScrolling is true, the search bar is visible only when the scroll position equals the top of your content view, that's in case you are using a UIViewController, which view property is a normal UIView (It is not a subclass of UIScrollView).
Instead, try to use UITableViewController or ScrollView, it should work as expected

In my case it was happening only when there was a small num of items in the table.
I came to a non-technical, but rather a logical solution to show the search bar only when there are >10 items in the list. There is no need to have search when you have only a few items anyway.

Try to add this
self.navigationItem.hidesSearchBarWhenScrolling = true

Related

iOS 11 tableView with searchBar issue

Please help to determine the reason of such behavior (it's hard to describe by words, so I recorded the short video) https://youtu.be/E2ks0liFX4I
In short words:
Initially it's able to scroll content beneath navigation bar. If press search field - the search bar looks like detached from table view and goes too high and overlapped by status bar (look at increased space between grey border of search bar and first row in the table). After Cancel button pressed - the search bar jumps down and now can't be hided by scrolling.
I'm using UITableViewController.
Search bar initialization in viewDidLoad:
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
tableView.tableHeaderView = searchController.searchBar
And in StoryBoard:
tableView settings
Not sure what u want. I guess u want the search bar to hide when scrolling?
I set searchbar to the navigationItem, then set the hidesSearchBarWhenScrolling property.
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true

Custom position for UISearchBar

I'm currently trying to implement UISearchController and its associated UISearchBar.
I aim to have a UISearchBar just above my UITableView which goes top as soon as it has the focus, like the picture below (screenshot from my old UI with UISearchDisplayController, now deprecated):
I already tried to set my UISearchBar as header of the UITableView, it works well but I have 2 issues :
The search bar logically scrolls with the table view content
When the search bar takes the focus, it remains at the same position
Here is the way I configured my UISearchBar:
func configureSearchController() { // Method called in the viewDidLoad()
searchController = UISearchController(searchResultsController: nil)
searchController!.searchResultsUpdater = self
searchController!.dimsBackgroundDuringPresentation = false
searchController!.searchBar.placeholder = "searchfood.searchbar.placeholder".localized
searchController!.searchBar.sizeToFit()
searchController!.hidesNavigationBarDuringPresentation = false
print(searchController!.searchBar.frame)
// Place the search bar view to the tableview headerview.
foodsTableView.tableHeaderView = searchController!.searchBar
// Search bar
searchController!.searchBar.searchBarStyle = .prominent
searchController!.searchBar.barTintColor = ColorLSDP.corail
searchController!.searchBar.tintColor = ColorLSDP.beige
}
So I tried to remove the following lines:
foodsTableView.tableHeaderView = searchController!.searchBar
But when I did this, I was not able to see the UISearchBar anymore.
After checking some other SO topics, I just spotted that my UISearchBar was maybe hidden below my UINavigationBar. So I tried to add the following lines in the viewDidLoad() method:
self.navigationController?.navigationBar.isTranslucent = false
self.edgesForExtendedLayout = []
It changed nothing.
Anyway, it did not solve my main issue which is having this search bar initially positioned like the screenshot above.
Is there a way to do this properly with the brand new UISearchController ?
Thanks a lot for your upcoming answers,
Regards,
Seb R.

UISearchController weird behavior on dismissing it

I am adding UISearchController searchBar to the controllers' view like this: self.view.addSubview(searchController.searchBar). The functionality is working perfectly fine except that upon selection of the tableview row the searchbar quickly moves down and reappears from the top. I tried the following things, none of which worked out:
Setting tableView.tableHeaderView = searchController.searchBar instead of directly adding to the view
Adding searchController.searchBar to a separate view that I dragged to the controller setting up constraints on it. Tried clipping to bounds both the newly created view and the searchBar.
Embedding the controller in UINavigationViewController and setting self.navigationItem.titleView = searchController.searchBar. I defined the frame of the searchBar, still nothing.
Tried playing with Extend Edges feature in the storyboard (Under top bars, etc.), but no selection worked out
Adding lines (to viewDIdLoad):
self.extendedLayoutIncludesOpaqueBars = true
self.definesPresentationContext = true
Any help would be greatly appreciated.
If you are using storyboards, you can change it by selecting the view controller and in the attributes inspector deselect Adjust scroll view insets.
After trying all of the suggestion and searching over the internet, it caught my eye that the working examples of the UISearchController implementation are done in UITableViewController, but I had UIViewController with UITableViewDataSource and UITableViewDelegate protocols on it. Unfortunately, due to app architecture I was not able to directly have UITableViewController, so I needed to restructure the app, so that it had UINavigationController where I embeded the searchBar in navigationItem.titleView (and not set it as tableView.tableHeaderView like they always do in various tutorials since I needed the searchBar to be fixed, not hidden when we do scrolling) and it worked. Here is how the ultimate working app architecture looks like:
The TrainingContainerViewController has two Container Views, in one we embed TrainingFilterTableViewController that shows up the ultimate results of the autocomplete functionality (after clicking on an autocomplete row). Another Container View embeds UINavigationController (to the left) which, in turn, has TrainingSearchTableViewController as its child.
The code that sets up the UISearchController and its searchBar is located in the TrainingSearchTableViewControllers' viewDidLoad and is the following:
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.sizeToFit()
searchController.delegate = self
navigationItem.titleView = searchController.searchBar
tableView.hidden = true
...
}
Nothing else was needed to fix the bug in XCode 8.2.1 and Swift 2.3, just change architecture, so that usage of UITableViewController is possible in the app and use it instead of UIViewController.

self.definesPresentationContext = true: leads to black screen?

let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
// searchController.definesPresentationContext = true
self.definesPresentationContext = true
When the search bar is active, with text in it, and I go to another tab and then back, the controller is black, apart from the actual search bar. Things go back to normal when I cancel and empty the search text field.
My question is basically identical to this question: UISearchController causes black screen Swift 2.0
Except that that answer does not solve my problem as you can see. What does solve it is if I change self to searchController, thus: searchController.definesPresentationContext = true. But this results in the search bar appearing in the next controller I tab to. Very confused, please help.
I am using a tableview embedded in a navigation controller and tab bar controller. viewDidDisappear is not being called when the search is active.
Not a solution per se, but a workaround, this stackeroverflow post helped:
TableView with SearchController - DEINIT not called. I am not sure if this is some kind of apple bug.
Apparently I am not supposed to use self.definesPresentationContext = true at all. This makes my search appear in all my tabs. But at least viewDidDisappear is called.
In viewDidDisappear, I can hide the search bar with searchController.searchBar.hidden = true and show the bar again in viewDidAppear.
in the AppDelegate.swift
window?.backgroundColor = UIColor.white

UISearchController and UISearchBar are not animating properly and are changing the Status Bar

I'm working in a fresh project with Xcode 7.2, built against iOS 9.2, and testing on an iPhone 6. This project is less than a week old with a minimal framework primarily defined in a storyboard.
The storyboard has a float of UINavigationController > UITabBarController > UITableViewController, which is the one with the search code, defined below.
In my Info.plist, I have Status bar style set to UIStatusBarStyleLightContent, Status bar is initially hidden set to YES, and View controller-based status bar appearance set to No.
In the storyboard, I do not have a UISearchBar or anything else on the UITableViewController other than the prototype UITableViewCell.
Nowhere in my simple app do I override preferredStatusBarStyle and on the storyboard I have made sure all the Status Bar values are set to Light Content for every controller, just to be safe.
The UITableViewController has the following code in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
searchResultsController = MovieSearchResultsController()
searchResultsController.tableView.delegate = self
searchController = UISearchController(searchResultsController: searchResultsController)
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = true
searchController.hidesNavigationBarDuringPresentation = true
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.tintColor = UIColor.whiteColor()
searchController.searchBar.sizeToFit()
self.tableView.delegate = self
self.tableView.tableHeaderView = searchController.searchBar
self.definesPresentationContext = true
}
When the UISearchBar is selected, the entire view shifts upwards, covering the UINavigationBar. This is great, except the status bar changes to black text and the UISearchBar disappears.
I'm pulling my hair out and have been pouring over this all day. I've read so many answers on Stack and nothing seems to work.
When I run Apple's UISearchController demo, it works exactly as intended. I've tried to replicate this exactly and I'm having no luck. I've also tried picking apart the demo and inserting my own code and it seems to work fine, short of completely redoing the project in this container, which seems highly unnecessary.
For the time being, I've just set searchController.hidesNavigationBarDuringPresentation to false and removed self.definesPresentationContext.
My Goal:
The status bar will remain with a white text color and the background color of my UINavigationBar.
The UINavigationBar will hide as the UISearchBar animates, shifting the view up.
The animation will flow smoothly, just like in the Apple demo. No jumpiness or strange delay.

Resources