class PlaceSelectorViewController: UIViewController, GMSAutocompleteResultsViewControllerDelegate, UISearchBarDelegate {
I have included searchbar delegate
searchController?.searchBar.delegate = self
and I have set the delegate.
But method
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
stopHighlight()
}
doesn't happen.
Delegate has set properly and stopHighlight() is a real function
Make delegate of searchbar in viewdidload method.
override func viewDidLoad() {
super.viewDidLoad()
searchBarCustom.delegate = self
}
or you can set it in storyboard as
-hence delegates will call as
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
print("searchBarCancelButtonClicked")
}
EDIT:
For UISearchController
var searchController: UISearchController!
func configureSearchController() {
// Initialize and perform a minimum configuration to the search controller.
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search here..."
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
// Place the search bar view to the tableview headerview.
tblSearchResults.tableHeaderView = searchController.searchBar
}
In my case, it was a spelling error.
Make sure your #IBOutlet name is similar with your delegate name.
Example,
#IBOutlet weak var SearchBar: UISearchBar!
Set the delegate in viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
SearchBar.delegate = self
Related
I am implementing a search feature in my app. The app consists of a view controller and a custom class that handles the search logic. This custom class is called SearchController.
My goal is to make the searchBar notify the view controller when the user is about to begin searching (exactly the same behaviour as the UISearchBarDelegate method searchBarShouldBeginEditing).
Normally, you would just declare searchBarShouldBeginEditing inside SearchController but I am trying to call this method from inside the viewController because I want something in my view to change when this event happens (and thus the viewController should be handling it, not the searchController).
SearchController class:
class SearchController: NSObject, UISearchBarDelegate {
let searchBar = UISearchBar()
var searchButton = UIBarButtonItem? = nil
/* Other irrelevant class properties */
func setup() {
searchBar.delegate = self
/* other setup */
}
}
ViewController class:
class ViewController: UIViewController {
private let searchController = SearchController()
override func viewDidLoad() {
super.viewDidLoad()
searchController.delegate = self
searchController.setup()
}
/* setup a tableview to display results... this part of the implementation works fine */
}
I omitted the majority of these two classes because the search feature already works. The only thing I am struggling with is finding a way to let viewController know when the user is about to begin typing into the search field.
I tried making viewController implement UISearchBarDelegate but I am already making SearchController implement UISearchBarDelegate so why can't I access the delegate methods inside viewController?
I hope I made myself clear, I can clarify this post further if necessary. I have been tearing my hair out trying to figure this out on my own.
Ok, a searchBar cannot have 2 delegates, so you're gonna have to find a way to work around that.
One way to go about this is this:
protocol SearchControllerDelegate: class{
func searchBarDidBeginEditing()
}
class SearchController: NSObject, UISearchBarDelegate {
weak var delegate: SearchControllerDelegate?
private let searchBar = UISearchBar()
func setup() {
searchBar.delegate = self
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
delegate?.searchBarDidBeginEditing()
}
}
class ViewController: UIViewController, SearchControllerDelegate{
var searchController = SearchController()
func setUP(){
self.searchController.delegate = self
}
func searchBarDidBeginEditing() {
/// perform some action here
}
}
You can use UISearchController as rmaddy suggested, implement UISearchResultsUpdating
ViewController class:
class ViewController: UIViewController, UISearchResultsUpdating {
private let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.delegate = self
....
}
// Called when the search bar's text or scope has changed or when the search bar becomes first responder.
func updateSearchResults(for searchController: UISearchController) {
//Do something...
}
}
Or if you really want to implement the search bar logic yourself, you can go with the closure:
SearchController class:
class SearchController: NSObject, UISearchBarDelegate {
let searchBar = UISearchBar()
var searchButton = UIBarButtonItem? = nil
var didBeginSearching: (() -> ())?
/* Other irrelevant class properties */
func setup() {
searchBar.delegate = self
/* other setup */
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
didBeginSearching?()
}
}
ViewController class:
class ViewController: UIViewController {
private let searchController = SearchController()
override func viewDidLoad() {
super.viewDidLoad()
searchController.setup()
searchController.didBeginSearching = { [weak self] in
//Do something...
}
}
}
How can I fix the search controller animate UI screen when adding to navigation item to the search bar in IOS 11?
I have tested it for iPhone X and its working fine. Make sure your navigation controller isn't nil in viewcontroller.
class ViewController: UIViewController {
var searchController: UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.searchBar.delegate = self
self.searchController.dimsBackgroundDuringPresentation = true
navigationItem.titleView = searchController.searchBar
definesPresentationContext = true
// Do any additional setup after loading the view, typically from a nib.
}
}
extension ViewController: UISearchBarDelegate {
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
// self.dismiss(animated: true, completion: nil)
}
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
search(sender: searchBar)
}
}
I have AllOrganizacionUIView class, I used UISearchBarDelegate delegate, on workink
class AllOrganizacionUIView: UIView , UISearchBarDelegate {
#IBOutlet var SearchBar: UISearchBar!
var searchActive : Bool = false
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchActive = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchActive = false;
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
aa.SearchBar.endEditing(true)
print("hajox")
}
}
I Have use UISearchBarDelegate delegate in ViewController class,
class ViewController: UIViewController{
#IBOutlet var SearchBar: UISearchBar!
// not working
func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
self.CircleImageView_3.image = UIImage(named: "FullCircle")
self.CircleImageView_2.image = UIImage(named: "Circle")
self.CircleImageView_1.image = UIImage(named: "Circle")
self.mMainCategory.hidden = true
self.mAllCategores.hidden = true
self.mAllOrganizations.hidden = false
self.FooterViewController.text = "Основные категории"
return true
}
}
Help me please with this problem.
You have to set delegate for your search bar, possibly in viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
self.SearchBar.delegate = self
}
But it will be much better if you point the delegate on storyboard instead of code.
So, I see two problems in your code. First, you mean that your delegate is an UIView subclass. But then you mean that you want to use delegate which is implemented in UIViewController subclass.
You're able to have only one delegate at the same time. Choose one (view controller is preferred), and implement all delegate methods there. Then just set delegate as I said at the beginning of my answer.
Actually, I suggest you to read about protocols and delegates at the official Apple's documentation website. It is really necessary to read documentation carefully, because there are a lot of unique things in iOS that are different to another platforms.
override func viewDidLoad() {
super.viewDidLoad()
self.SearchBar.delegate = self
}
or set your delegate in storyboard .
I am trying to implement the search in my SWIFT code. I want it to wait until the search button is clicked before it does anything. What I have so far.
func updateSearchResultsForSearchController(searchController: UISearchController)
{
self.filteredCats.removeAll(keepCapacity: false)
filteredCats = art.filter{
$0.sarticleTitle.lowercaseString.rangeOfString(searchController.searchBar.text!.lowercaseString) != nil
}
print(searchController.searchBar.text)
self.tableView.reloadData()
}
It prints out all the information once the user types something. I want it to wait till the search button is clicked or when the user has finished typing everything.
You should set delegate like this your view controller.
var resultSearchController = UISearchController()
resultSearchController.searchBar.delegate = self
extension ViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
print("search button click")
}
}
Use the UISearchBarDelegate method searchBarSearchButtonClicked(_:) Reference
class MySearchController:UISearchController, UISearchBarDelegate {
override init(searchResultsController: UIViewController?) {
super.init(searchResultsController: searchResultsController)
// Set the searchbar delegate
self.searchBar.delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
// Start the search
}
}
Importantly, make sure you tell the UISearchBar that you want the UISearchController to be it's delegate, the above is an un-tested example, your exact initialisation may differ.
implement "searchController.searchBar.delegate" & "searchBarSearchButtonClicked" method
self.searchController.searchBar.delegate = self;
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
//enter your search code
}
I'm trying to find an alternative to displaysSearchBarInNavigationBar for iOs8, is there anything I can use (in swift)?
I tried self.navigationItem.titleView = resultSearchController.searchBar but it doesn't do anything.
I don't understand how to find the replacement for functions that are deprecated, on the apple documentation it just say deprecated with no alternative, if you have any tips it would be greatly appreciated.
You can put an UISearchBar in a UINavigationBar without using a UINavigationController without problem, but you have to do a minor change only, first you need to define an #IBOutlet to the UINavigationItem inside your UINavigationBar but its name need to be different from the navigationItem property defined in all the UIViewController class, see the following code:
class ViewController: UIViewController, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate {
var searchController : UISearchController!
#IBOutlet weak var navigationItemBar: UINavigationItem!
override func viewDidLoad() {
super.viewDidLoad()
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = true
self.navigationItemBar.titleView = searchController.searchBar
self.definesPresentationContext = true
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
And then you can see something like this in your simulator:
I hope this help you.