I am trying to use UISearchController to display a search bar along with scope bar in iOS 11.
Here is the code that I am using to setup the search controller
let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.showsScopeBar = true
searchController.searchBar.scopeButtonTitles = ["1", "2", "3", "4"]
searchController.searchBar.delegate = self
definesPresentationContext = true
I want a search bar with a scope bar that is always visible.
The above code works fine when the view controller loads and it displays the search bar along with the scope bar.
But, once the search controller becomes active and is then dismissed, iOS hides the scope bar on dismiss of the search controller and it only displays the search bar.
I tried to solve this issue by adding the following code in didDismissSearchController, but the scope bar and the search bar comes on top of each other instead of the scope bar coming below the search bar (like the image below). Adding this code to searchBarTextDidBeginEditing(_ searchBar: UISearchBar) or searchBarTextDidEndEditing(_ searchBar: UISearchBar) has no effect.
searchController.searchBar.showsScopeBar = true
searchController.searchBar.sizeToFit()
Try adding this this to your search controller setup:
searchController.sizeToFit()
Then add this:
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
self.searchBar.sizeToFit()
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
self.searchBar.sizeToFit()
return true
}
Don't put searchController.searchBar.showsScopeBar = true in the search bar functions. That creates a problem for some reason.
Related
I am showing searchbar in home page. When I push a UIViewController then get back to home page, the searchbar become hidden.
here is my code
func setupSearch(){
searchController = UISearchController(searchResultsController: resultsTableController)
searchController.searchResultsUpdater = self
searchController.searchBar.autocapitalizationType = .none
searchController.searchBar.searchTextField.placeholder = "Enter a search term...".localized()
searchController.searchBar.returnKeyType = .search
// Place the search bar in the navigation bar.
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = true
// searchController.hidesNavigationBarDuringPresentation = false
// Monitor when the search controller is presented and dismissed.
searchController.delegate = self
// Monitor when the search button is tapped, and start/end editing.
searchController.searchBar.searchTextField.delegate = self
/** Specify that this view controller determines how the search controller is presented.
The search controller should be presented modally and match the physical size of this view controller.
*/
definesPresentationContext = true
}
Im running into a problem when I preform a search, I can't get the search bar to reset from it's focused state (The background view is dimmed and the cancel button is still in the search bar. I want to clear the search bar and NOT have the background dimmed).
The view controller has the following (in the view did load):
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.placeholder = "Search here"
searchController.searchBar.searchBarStyle = .minimal
self.navigationItem.searchController = searchController
When I tap search, I get have the following:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.endEditing(true)
searchBar.resignFirstResponder()
searchBar.text = ""
self.navigationItem.searchController?.resignFirstResponder()
}
The searchBar.endEditing(true) doesn't seem to be doing anything. Nor the resignFirstResponder. The background of the view is still dimmed.
For reference, the view controller is embedded in a nav controller, which in part a tab bar view controller (if that matters). And after the search is made, I push another view controller on the stack (hence why I want to clear the search bar and reset it's state when the view controller is shown again).
I've added some pictures to show the problem visually. The second photo is what Im left with after search is pressed when I want to to reset and look like the first photo.
self.navigationItem.searchController?.isActive = false is apparently what I'm looking for
Left side displays my app in the iPhone 7 simulator. Right side is the app as displayed in my device. When tapping in the search bar, the navbar sildes up but then slides back down as showing in the image with the "What is this?" text.
The code for my search controller is as follows and it is being called in viewDidLoad.
//MARK: - Search Controller
func configureSearchController() {
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
// to receive updates
searchController.searchResultsUpdater = self
// Set up searchbar of search controller
searchController.searchBar.scopeButtonTitles = ["All", "Something", "Something"]
searchController.searchBar.delegate = self
// add the searchbar to the tableview
tableView.tableHeaderView = searchController.searchBar
// hack to fix ocassional bugs
searchController.searchBar.sizeToFit()
}
In iOS 11 you can put a UISearchController in the NavigationBar with a few lines of code.
I set up everything in the ViewController.swift.
func setupNavBar() {
navigationController?.navigationBar.prefersLargeTitles = true
let searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = wordViewController
searchController.searchBar.scopeButtonTitles = ["French", "English"]
searchController.searchBar.delegate = wordViewController
navigationItem.searchController = searchController
// Make searchbar persistent
navigationItem.hidesSearchBarWhenScrolling = false
}
In my delegate, the search fires and filters properly. However, if I click either of the scope buttons, they simply disappear. This delegate method is never called. (filter by scope is not actually implemented yet)
extension WordViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
if let searchText = searchBar.text {
print("Scoped changed: \(searchText)")
filteredWordList = wordList.filter({$0.contains(searchText)})
}
}
}
Full source is on Github:
https://github.com/melling/ios_topics/tree/master/NavBarSearch
https://github.com/melling/ios_topics/tree/master/NavBarSearch/NavBarSearch
Try to add this code within setupNavBar():
searchController.dimsBackgroundDuringPresentation = false
I was able to use Artem's solution,
searchController.dimsBackgroundDuringPresentation = false
but I then ran into the problem of no longer being able to click on the background to dismiss the focus on the search bar.
To resolve this, I created my own dimmer uiview (screen size, background color of black with 25% opacity), and added that to the view of the currently presented screen, and listened for a tap. When the user taps it, I fade it out and set
searchController.active = false
In your ViewController, you need to add this line
self.definesPresentationContext = YES;
This tells the UISearchController the presentation context it needs to use, which is defined by your ViewController.
Check this link for more details: http://asciiwwdc.com/2014/sessions/228
I'm trying out UISearchController for iOS 8 right now. When I click the cell, it will push the segue and show another view controller. However, the search controller/bar is still there on the next controller. Also, I notice that the status bar background is white, while it should be grey as the searchBar background color is grey. Is there anything that I miss?
This is the codes that I used to initialise the search controller
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.sizeToFit()
tableView.tableHeaderView = searchController.searchBar
}
Screenshot:
Manual stop UISearchController in prepareForSegue
searchController.active = false
Or add this in viewDidLoad
searchController.definesPresentationContext = true