I am trying to autofocus a searchbar when i click on a bar button, but it does not seem to work with becomeFirstResponder, follow the GIF:
I've already tried using becomeFirstResponder and it does not work, this is how i am handling the searchbar:
// MARK: SearchBar Delegate
#IBAction func showSearchBarAction(_ sender: Any) {
let searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.searchBar.keyboardAppearance = .dark
searchController.dimsBackgroundDuringPresentation = false
navigationItem.searchController = searchController
navigationItem.searchController?.isActive = true
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
navigationItem.searchController?.isActive = false
self.navigationItem.searchController = nil
}
All of it works perfectly, but the autofocus is something i really want and i can't change my design as well
Solution
This code is the solution:
This is how my class declaration looks like:
class YourViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate, UISearchControllerDelegate {
// MARK: SearchBar Delegate
#IBAction func showSearchBarAction(_ sender: Any) {
let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.searchBar.keyboardAppearance = .dark
searchController.dimsBackgroundDuringPresentation = false
self.navigationItem.searchController = searchController
self.navigationItem.searchController?.isActive = true
}
func didPresentSearchController(_ searchController: UISearchController) {
DispatchQueue.main.async {
searchController.searchBar.becomeFirstResponder()
}
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
navigationItem.searchController?.isActive = false
self.navigationItem.searchController = nil
}
Related
i want to disable right cancel button when a tap at search Bar.
Because of using Google Place search i put i should use searchController?.searchBar
I try to disable cancel button at
func presentSearchController(_ searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
but when i tap a searchBar i see how cancel button appear and disappear, thats looks ugly
Please give me advice!
override func viewDidLoad() {
super.viewDidLoad()
resultsViewController = GMSAutocompleteResultsViewController()
resultsViewController?.delegate = self
searchController = UISearchController(searchResultsController: resultsViewController)
searchController?.searchResultsUpdater = resultsViewController
searchController?.searchBar.sizeToFit()
navigationItem.titleView = searchController?.searchBar
searchController?.searchBar.placeholder = searchBarPlaceholderText
searchController?.searchBar.tintColor = #colorLiteral(red: 0.1019607843, green: 0.5490196078, blue: 1, alpha: 1)
searchController?.searchBar.delegate = self
searchController?.delegate = self
searchController?.searchBar.searchBarStyle = .prominent
definesPresentationContext = true
mapView.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
checklocationAuthorizationStatus()
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
locationManager.startUpdatingLocation()
}
func presentSearchController(_ searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
You can create a custom class and subclass UISearchBar and UISearchViewController.
For example:-
class CustomizedSearchBar: UISearchBar {
override func layoutSubviews() {
super.layoutSubviews()
setShowsCancelButton(false, animated: false)
}
}
Now Create Object of the CustomizedSearchBar and use it within other viewController.
Or you can create a customized searchViewController as follows:
class CustomizedSearchController: UISearchController, UISearchBarDelegate {
lazy var _searchBar: CustomSearchBar = {
[unowned self] in
let result = CustomSearchBar(frame: CGRectZero)
result.delegate = self
return result
}()
override var searchBar: UISearchBar {
get {
return _searchBar
}
}
}
Please follow this link for more detail information.
I have set up a search bar using the embed nav bar. The func searchBarSearchButtonClicked is not being detected. I'd like to make it so that when the user taps on the search bar, another function will be called. I've taken out some extraneous code not relevant to this question. What could be the issue?
class FirstViewController: UIViewController, UISearchBarDelegate {
var resultSearchController: UISearchController? = nil
override func viewDidLoad() {
super.viewDidLoad()
// set up the search results table
let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable") as! LocationSearchTable
resultSearchController = UISearchController(searchResultsController: locationSearchTable)
resultSearchController?.searchResultsUpdater = locationSearchTable
let searchBar = resultSearchController!.searchBar
searchBar.sizeToFit()
searchBar.placeholder = "Where would you like to go"
navigationItem.titleView = resultSearchController?.searchBar
searchBar.delegate = self
resultSearchController?.hidesNavigationBarDuringPresentation = false
resultSearchController?.dimsBackgroundDuringPresentation = true
definesPresentationContext = true
}
func searchBarSearchButtonClicked(_: UISearchBar) {
// closeMapType()
// self.mapType.transform = .identity
print("it worked")
}
}
Below function will call when the user taps on the search bar :
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
return true
}
This will call when we click on the "Search" button in the keyboard
func searchBarSearchButtonClicked(_: UISearchBar)
I'm trying to get a UISearchController working in my navigation bar using swift3
I currently have it so a search icon exists in the top right corner. When you click on the icon, it will show you the UISearchController.
The problem is, when I try to do searchController.delegate = self, I get an error saying
Cannot assign value of type 'ParentViewController' to type 'UISearchControllerDelegate'?
I'm assuming since I can't set the delegate, none of the actions are linked, but I can't figure out why it won't let me?
Here's the code I'd like to work. Am I implementing the protocol wrong and just not seeing it, or missing something entirely?
class ParentViewController: ButtonBarPagerTabStripViewController, UISearchResultsUpdating, UISearchBarDelegate {
var searchBarButtonItem: UIBarButtonItem?
override func viewDidLoad() {
searchBarButtonItem = navigationItem.rightBarButtonItem
super.viewDidLoad()
}
func updateSearchResults(for searchController: UISearchController) {
print("update search results")
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
print("search cancelled")
}
func filterContentForSearchText(searchText: String, scope: String = "All") {
print("Filter: " + searchText)
}
#IBAction func startSearchAction(sender: UIBarButtonItem) {
print("Clicked")
let searchController = UISearchController(searchResultsController: nil)
searchController.delegate = self
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.showsCancelButton = true
searchController.dimsBackgroundDuringPresentation = true
self.navigationItem.titleView = searchController.searchBar
definesPresentationContext = true
navigationItem.setRightBarButton(nil, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I try to show searchController in UIViewcontroller.
This works fine but when I try to write something then search controller is not visible.
My code is as follow:
class tempVC: UIViewController,UISearchBarDelegate,UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Enter name here..."
definesPresentationContext = true
searchController.searchBar.sizeToFit()
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation=false
//navigationItem.titleView = searchController.searchBar
searchController.searchBar.frame=CGRectMake(0, 64, 320, 44)
self.view.addSubview(searchController.searchBar)
}
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResultsForSearchController(searchController: UISearchController) {
// let searchBar = searchController.searchBar
//let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
//filterContentForSearchText(searchController.searchBar.text!, scope: scope)
print("update")
}
}
Please help me to solve this.
Thank you,
class tempVC: UIViewController,UISearchBarDelegate,UISearchResultsUpdating {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
searchController.searchBar.placeholder = "Enter name here..."
definesPresentationContext = true
searchController.searchBar.sizeToFit()
searchController.dimsBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation=false
//navigationItem.titleView = searchController.searchBar
searchController.searchBar.frame=CGRectMake(0, 64, 320, 44)
self.view.addSubview(searchController.searchBar)
}
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResultsForSearchController(searchController: UISearchController) {
// let searchBar = searchController.searchBar
//let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
//filterContentForSearchText(searchController.searchBar.text!, scope: scope)
print("update")
}
}
I'm trying to hide the Cancel button of the search bar in the UISearchController, but unfortunately setting the following in viewDidLoad() does not work:
override func viewDidLoad() {
super.viewDidLoad()
searchResultsTableController = UITableViewController()
searchResultsTableController.tableView.delegate = self
searchController = UISearchController(searchResultsController: searchResultsTableController)
searchController.searchResultsUpdater = self
searchController.searchBar.sizeToFit()
searchResultsView.tableHeaderView = searchController.searchBar
searchController.delegate = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.delegate = self
searchController.searchBar.searchBarStyle = .Minimal
searchController.searchBar.showsCancelButton = false
definesPresentationContext = true
}
I have also tried using the above code in this delegate method:
func didPresentSearchController(searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
This approach works but will show the Cancel button briefly before hiding it, which is not ideal. Any suggestions?
I ended up subclassing both UISearchBar and UISearchController as suggested:
CustomSearchBar.swift
import UIKit
class CustomSearchBar: UISearchBar {
override func layoutSubviews() {
super.layoutSubviews()
setShowsCancelButton(false, animated: false)
}
}
CustomSearchController.swift
import UIKit
class CustomSearchController: UISearchController, UISearchBarDelegate {
lazy var _searchBar: CustomSearchBar = {
[unowned self] in
let result = CustomSearchBar(frame: CGRectZero)
result.delegate = self
return result
}()
override var searchBar: UISearchBar {
get {
return _searchBar
}
}
}
Rejoice! As of iOS 13, there is access to automaticallyShowsCancelButton on UISearchController. Set it to false to hide the cancel button.
func didPresentSearchController(_ searchController: UISearchController) {
searchController.searchBar.becomeFirstResponder()
searchController.searchBar.showsCancelButton = true
}
func didDismissSearchController(_ searchController: UISearchController) {
searchController.searchBar.showsCancelButton = false
}
In my case all the above solutions dint work. You need to show in didPresentSearchController and hide it in didDismissSearchController. Earlier I was just hiding in didDismissSearchController which was still showing Cancel button on cancelling.
Hide the Cancel button in search bar delegate methods and set your delegate searchController.searchBar.delegate=self UISearchBarDelegate
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
}
Try subclassing UISearchBar and implement:
override func layoutSubviews() {
super.layoutSubviews()
self.setShowsCancelButton(false, animated: false)
}
This SO thread may help you more in this direction.
The same answer as given by #Griffith and #Abhinav but using extension:
extension UISearchBar {
override open func layoutSubviews() {
super.layoutSubviews()
setShowsCancelButton(false, animated: false)
}
}
This code is from Swift 4.