How to know when search bar text changes [duplicate] - ios

This question already has answers here:
Searching a table view with UISearchBar
(2 answers)
Closed 9 years ago.
I have a search bar and I need to get a notification when the bar text changes, how can I do that? I need to reload the table view every time the string value of the search bar changes

Follow the below steps to get it done
Add Delegate methods for your View Controller
ViewController: UISearchBarDelegate, UISearchDisplayDelegate
Create IBOutlet for your searchBar
#IBOutlet weak var searchBarVar: UISearchBar!
Assign Delegates as self to searchBar in viewDidLoad.
override func viewDidLoad() {
super.viewDidLoad()
searchBarVar.delegate = self
}
Implement the textDidChange delegate method
Swift 4:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText",searchText)
}
ObjC
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText;

Related

UISearchBar searchBarCancelButtonClicked not being called using Swift 3

For some reason when I click the circle x cancel button in a UISearchBar the searchBarCancelButtonClicked event is not firing, it worked in a swift 2 project but not in this swift 3 one.
I am now extending my view controller instead of the inline class way but I believe that is working as the searchBarSearchButtonClicked event does work. Here is what I have so far:
extension MyViewController: UISearchBarDelegate {
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
print("here?")
searchBar.resignFirstResponder()
handleCancelSearch()
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
if let searchText = searchBar.text {
performSearchUsing(term:searchText)
}
}
}
The print is not logged and the function not called. Am I missing something silly?
Maybe you are missing something silly as I did, the "circle x" is not actually the cancel button, and I thought that too, the cancel button comes disabled by default, you can activate it via storyboard on the attributes of the searchBar or you can do it programmatically with:
searchBar.showsCancelButton = true
After that, the method should work.
If any one still looking for the option how act on "X" button. use below method which is available in
UISearchBarDelegate
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
{
if searchText.count == 0
{ // Hide content
}
}
Note : it is not cannel button its clear text button which is visible after typing something in searchBar

How to clear multiple textviews upon Editing?

I am trying to clear multiple textviews on editing. I know how do so with one textView (IE):
class ViewController: UIViewController, UITextViewDelegate {
#IBOutlet weak var myTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
myTextView.delegate = self
}
func textViewDidBeginEditing(textView: UITextView) {
myTextView.text = ""
}
How would I use the same concept for multiple textviews?
func textViewDidBeginEditing(textView: UITextView) {
myTextView.text = ""
}
The above delegate method will get called when a text view begins editing. And this method holds the reference to the textView that called in the textView object. You can use that reference to clear the text instead of using a separate reference/outlet to the textView.
So the method would be:
func textViewDidBeginEditing(textView: UITextView) {
textView.text = ""
}
From the Documentation:
Description:
Tells the delegate that editing began in the specified text field.
This method notifies the delegate that the specified text field just
became the first responder. Use this method to update state
information or perform other tasks. For example, you might use this
method to show overlay views that are visible only while editing.
Implementation of this method by the delegate is optional.
Parameters:
textView
The text view in which an editing session began.

updateSearchResultsForSearchController not called in iOS 9

I am trying to write a simple UITableView with a UISearchBar. I have no problem when I drag and drop a UITableViewController. Everything works! (see code below)
override func viewDidLoad() {
super.viewDidLoad()
self.searchResultsController = UISearchController(searchResultsController: nil) //initialize the search controller
self.searchResultsController.searchResultsUpdater = self //the search controller updater is this view
self.searchResultsController.dimsBackgroundDuringPresentation = false
self.searchResultsController.searchBar.sizeToFit()
self.searchResultsController.searchBar.searchBarStyle = UISearchBarStyle.Minimal
self.searchResultsController.searchBar.showsCancelButton = true
self.tableView.tableHeaderView = searchResultsController.searchBar
self.tableView.reloadData()
}
But now, for experimental purpose, I used UIViewController, and added a UITableView, no problem with showing my records in the table.
Then, added a UISearchBar from the storyboard, set its delegate to the UIViewController, but the updateSearchResultsForSearchController method is not called when the user type in something.
It's like my UISearchController has no idea there is a UISearchBar, and what ever I type in, does not evoke the updating method. Do I have to tell the UISearchController that hey this is your UISearchBar?
So here's top of my code:
class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate, UISearchControllerDelegate
{
#IBOutlet weak var mySearchBar: UISearchBar!
#IBOutlet weak var myViewTable: UITableView!
let allElements = ["H", "Li", "Na", "K", "Rb", "Cs", "Fr"]
var filteredElemetns = [String]()
var searchResultsController = UISearchController() //create a new search controller
override func viewDidLoad()
{
super.viewDidLoad()
self.searchResultsController = UISearchController(searchResultsController: nil) //initialize the search controller
self.searchResultsController.searchResultsUpdater = self //the search controller updater is this view
self.searchResultsController.dimsBackgroundDuringPresentation = false
self.searchResultsController.searchBar.sizeToFit()
self.searchResultsController.searchBar.searchBarStyle = UISearchBarStyle.Minimal
self.searchResultsController.searchBar.delegate = self
//self.myViewTable.tableHeaderView = self.searchResultsController.searchBar
}
If I uncomment the last line, then I'll have two UISearchBar, which one is added by the storyboard and the other one with the last line code. The one I added, does not work, but the one at top of the myViewTable does.
Ok, I found the solution.
I used my filtering algorithm inside searchBar:textDidChange function. Then everything worked, and I don't need updateSearchResultsForSearchController function anymore. Here is my code:
func searchBar(searchBar: UISearchBar, textDidChange searchText: String)
{
print("filtering...")
self.filteredElemetns.removeAll(keepCapacity: false) //remove all the elements
let searchPredict = NSPredicate(format: "SELF CONTAINS [c] %#", self.mySearchBar.text!)
print(searchPredict)
let foundElements = (self.allElements as NSArray).filteredArrayUsingPredicate(searchPredict)
self.filteredElemetns = foundElements as! [String]
self.myViewTable.reloadData()
}
Of course, don't forget to make sure your class conforms to UISearchBarDelegate protocol.
I find this approach better than using a UITableViewController. One reason, if you search, you will find that many people have a problem with making UISearchBar the first responder. The only solution to that, I found, is calling becomeFirstResponder after a delay, which is really not a good programming approach.
But, with this approach, you can make an outlet of your UISearchBar and then easy make it the first responder in viewDidAppear.
I know some people might say no you can easily make the UISearchBar the first responder even if you use UISearchResultsController by doing something like:
self.searchResultsController.searchBar.becomeFirstResponder()
self.searchResultsController.active = true
But, believe me in iOS 8/9 it is not that simple, it won't work. Try it...

Get searchbar text in swift

I want to use search bar in my app. But I couldn't find any tutorial for this.
My question is simple: How can I get search bar text when user preses to enter button ?
I need something like this in my view controller:
override func userPressedToEnter(text: String) {
println("User entered: \(text)")
}
How can I do this in swift ?
Assuming you have a simple search bar in your storyboard, make sure you have it connected as an outlet. Then use this as an example. Use UISearchBarDelegate the reference to learn more about delegate methods available to you.
import UIKit
class ViewController: UIViewController, UISearchBarDelegate {
#IBOutlet var searchBar:UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
searchBar.delegate = self
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
print("searchText \(searchText)")
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
print("searchText \(searchBar.text)")
}
}
I would take a look at the UISearchBarDelegate protocol:
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UISearchBarDelegate_Protocol/index.html
Make your view controller class conform to this protocol and you will have everything you need to interact with your search bar. Alternatively you can get at the search bar text field but Apple gives you a much cleaner, nicer, event driven way via this protocol.
Assuming you have a tableview that you're searching, add a Search Bar and Search Controller to the tableview in the storyboard. That'll hook up all the data source / delegate connections that you need.
Then in your tableview you can use:
func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
doStuffWithSearchText(searchBar.text, scope: 0)
}
which will get called whenever they change the text in the search bar. It's common to update the data that's displayed every time they change the text but if you need to do it only when they tap on the search button use this function instead:
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
doStuffWithSearchText(searchBar.text, scope: 0)
}
And you can get the text from the search results controller:
controller.searchBar.text
Or from the search bar:
searchBar.text
If you're not using a tableview controller:
Add a search bar
Hook up your view controller as the search bar's delegate
Then use the searchBarSearchButtonClicked: function to handle when they tap the "Search" button or searchBar(searchBar: UISearchBar, textDidChange searchText: String) to handle w
I wrote a tutorial on doing it with a table view controller that has all the gritty details: Adding a Search Bar to a Table View in Swift

UISearchBar triggered functions

My entire app interface is made programatically from ViewController.swift
Inside the view is UISearchBar. What are the names of functions which I can override in order to run my own code when UISearchBar is tapped on, when the keyboard's Search button is pressed and when UISearchBar's Cancel button is pressed?
If they don't exist, can I trigger my own functions at those times?
You'll want to add conformance to the UISearchBarDelegate protocol to your view controller:
extension ViewController : UISearchBarDelegate {
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
// ...
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
// ...
}
}
and then set the search bar's delegate to self.
If you use the UISearchBarDelegate you can implement the following methods...
//Becomes first responder
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;
//Editing begins
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar;
//Cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar;

Resources