I have set the delegate in the viewDidLoad() method and also checked the IB to see if the delegate shows up when using (control + drag) and it does infact show as being hooked up. I deleted it as well and added a new SearchBar entirely in IB and hooked it back up. Nothing seems to do the trick. Any suggestions?
override func viewDidLoad() {
self.searchBar.layer.zPosition = 1
self.searchBar.delegate = self
}
//this is never being called, breakpoint never hits
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText \(searchText)")
}
//this is never being called, breakpoint never hits
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
print("search button clicked")
self.firebaseQuery()
}
Is your custom View Controller class set in Interface Builder? I.e. on the Identity Inspector tab, ensure your desired UIViewController subclass is set in the Custom Class section.
Also, try setting a breakpoint in viewDidLoad(). Run the app and if the breakpoint doesn't get hit when you expect, that helps narrow down the problem.
Is it possible you're setting the delegate incorrectly?
In Interface Builder, command-click the search bar, drag the delegate to the yellow ViewController button in the storyboard to set the delegate.
Remove self.searchBar.delegate = self from viewDidLoad()
I'm also not seeing if your viewController Class has properly conformed to UISearchBarDelegate I would add it in an extension to your controller and put all your code relating to it there.
class ViewController: UIViewController{...}
extension ViewController: UISearchBarDelegate {
// implement all searchBar related methods here:
func searchBarButtonClicked(_ searchBar: UISearchBar) {
//capture the string
if let input = searchBar.text {
// do something with string.
print(input)
}
}
I also had a problem with it not responding when I set it up using IB. I finally set it up using code instead of IB, and it worked. Try it this way:
class MySearchTableViewController: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
self.searchController.searchBar.autocapitalizationType = UITextAutocapitalizationType.none
self.navigationItem.searchController = self.searchController
//if this is set to true, the search bar hides when you scroll.
self.navigationItem.hidesSearchBarWhenScrolling = false
//this is so I'm told of changes to what's typed
self.searchController.searchResultsUpdater = self
self.searchController.searchBar.delegate = self
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
//hopefully this gets called when you click Search button
}
func updateSearchResults(for searchController: UISearchController) {
//if you want to start searching on each keystroke, you implement this method. I'm going to wait until they click Search.
}
https://www.reddit.com/r/swift/comments/85o75h/bug_uisearchbar_delegate_methods_not_being_called/dvzcbb4/
Thanks to reddit user #applishish I got the issue
I did not put a underscore in front of the parameter -_-
Thanks all for your help!
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...
}
}
}
class PlaceSelectorViewController: UIViewController, GMSAutocompleteResultsViewControllerDelegate, UISearchBarDelegate, UISearchControllerDelegate {
I have UISearchBarDelegate in my class
searchController?.searchBar.delegate = self
and I had set the delegate to Self.
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
stopHighlight()
}
But this Delegate call is not working
You need an outleet for your UISearchBar (assuming you're working with Storyboard this is really easy, just drag and drop via Assistant Editor). and that's what you're going to add the delegate to. In case you built programmatically, then that variable is the one that's going to get assigned to the delegate.
Here's the example code for the Storyboard built
#IBOutlet weak var searchBar: UISearchBar! (you must see a filled circle at the right of this, otherwise there's no link between Storyboard and this outlet)
...
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
}
I have 2 Controllers and one is a SubView. The MainController has access to the SearchBar property and the SubViewController does not . There is a SearchBar function in the Main Controller that I would like to invoke in the SubView Controller it is this function
// MainController
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
// Stop doing the search stuff
// and clear the text in the search bar
searchBar.text = ""
// Hide the cancel button
searchBar.showsCancelButton = false
searchBar.endEditing(true)
Popup.Close_View()
}
What I am trying to do is wrap that function above in another function like this
func Selected_Location() {
searchBarCancelButtonClicked(SearchBar)
}
so that in my SubView Controller I can do
// SubView Controller
let Select_Close = MainController()
Select_Close.Selected_Location()
I am new to Swift and as stated before how can I get the searchBarCancelButtonClicked function and call it inside another function with ? I have tried doing it in several ways such as
func Selected_Location() {
searchBarCancelButtonClicked(_ searchBar: UISearchBar)
}
func Selected_Location() {
searchBarCancelButtonClicked(searchBar)
}
Again my SubView Controller does not have access to a UISearchBar so I am trying to call the SearchBar close function from within the SubView.
In Subview, keep weak reference of MainViewController, and then call one method of mainviewcontroller searchBarCancel
class MainViewController:UIViewController {
var subViewController: SubViewController
func searchBarCancel(){
searchBarCancelButtonClicked(self.searchBar)
}
func func2(){
subViewController.mainController = self
}
}
class SubViewController:UIView {
weak var mainController: MainViewController?
func Selected_Location() {
mainController!.searchBarCancel()
}
}
So I am messing around with user queries using Parse. I have a table view as my data source within a UIViewController, and I am using an extension on it like so
extension addFriend: UISearchBarDelegate, UISearchDisplayDelegate {
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
print("worked")
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
print("editing")
searchBar.setShowsCancelButton(true, animated: true)
state = .SearchState
}
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
searchBar.text = ""
searchBar.setShowsCancelButton(false, animated: true)
state = .DefaultState
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
Reachability.searchUsers(searchText, block: updateList)
}
}
specifically for my search bar declared as
#IBOutlet weak var searchBar: UISearchBar!
Reachability is a public class with my query functions e.g. searchUsers().
I am using a model described here
https://www.makeschool.com/tutorials/build-a-photo-sharing-app-part-2/friend-search-follow
but for some reason the search bar is not working. The print statements are there to verify this fact, and I have tried adopting the search bar delegates at class declaration and typing search bar functions within the class as I had written similar code not long before I tried this. It is not working and I can't exactly figure out why. I have done exactly this before and it worked just fine. I am new to swift programming, is there something I am missing? I would appreciate any help or shove in the right direction. Thanks in advance!
I have a class and use UICollectionViewController, UICollectionViewDelegateFlowLayout , UISearchBarDelegate
I want use searchbar in Navigation View , but when I clicked on Cancel Button or SearchButton , searchBarSearchButtonClicked and searchBarCancelButtonClicked , non of them was called.
but I use this function and this func was called :
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
println("search is working ")
}
this is my viewDidload func:
override func viewDidLoad() {
super.viewDidLoad()
let searchBar = UISearchBar()
searchBar.delegate = self
searchBar.sizeToFit()
navigationItem.titleView = searchBar
}
and this is search and cancel func:
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
println("cancel button called")
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
println("search button called")
}
So , what is wrong?
searchBar func is called when I write something in searchbar but
when click on searchButton and cancel button nothing happen!?
I use simulator iphone ,So search button is enter button of keyboard
but I used another button , then nothing happen.
now I use enter , and every thing is ok.
this is very funny!:D