I'm using UISearchBar when I input text on UISearchBar the keyboard shows. At that time, keyboard return key is "Search".
I want to implement event when I press the keyboard search button.
How can I implement the action?
On UITextField it has
-(BOOL)textFieldShouldReturn:(UITextField *)textField;
But on UISearchBar it doesn't have return action.
Thank you for your helping.
Add UISearchBarDelegate in .h
Also set SearchBar's object delegate to self.
Add this to the UISearchBarDelegate's method:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
// Do the search...
}
Swift
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
In Swift 3:
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
The textFieldShouldReturn method is a textField delegate method and not the one you're looking for. What you need is a UISearchBarDelegate method called searchButtonClicked, have a look here.
i Used following code in swift 5. implement UISearchBarDelegate then write following code in class keyboard will automatically hide on clicking search
class sample: UIViewController, UISearchBarDelegate {
let searchbar: UISearchBar = {
let sear = UISearchBar()
sear.tintColor = Mycolor().lightgray1
sear.backgroundColor = Mycolor().lightgray1
sear.barTintColor = Mycolor().lightgray1
sear.placeholder = "Search Asset"
sear.layer.cornerRadius = 30
sear.barStyle = .default
sear.backgroundImage = UIImage()
sear.returnKeyType = .search
// sear.addShadow(offset: CGSize(width: 10, height: 10), color: UIColor.darkGray, radius: 20, opacity: 5)
return sear
}()
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
}
Related
I have a SearchBar when i press the cancel button i have it set so that the textfield should have no text and all of my collection view cell's show
When the cancel button is tapped while there is still text in the TextField my collection view shows no cells until i go back into the search bar and press the delete button "X"
Would appreciate some help Thanks
Here is the code
print(" search button pressed")
navigationItem.titleView = searchBar
searchBar.searchTextField.backgroundColor = .black
searchBar.searchTextField.textColor = .white
searchBar.placeholder = "search for a contact"
searchBar.showsCancelButton = true
searchBar.becomeFirstResponder()
navigationItem.leftBarButtonItem = nil
navigationItem.rightBarButtonItem?.tintColor = .white
} else {
print(" cancel button pressed")
searchBar.searchTextField.text? = ""
navigationItem.titleView = nil
searchBar.showsCancelButton = false
navigationItem.rightBarButtonItem?.isEnabled = true
navigationItem.rightBarButtonItem?.tintColor = .purple
collectionView.reloadData()
Did you try assigning nil to searchBar.searchTextField.text? Maybe that can make a difference.
here's how I would check if I've done my implementation properly. Make sure I'm calling necessary delegate methods for UISearchBarDelegate and handle filter there.
extension MyViewController: UISearchBarDelegate {
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsCancelButton = true
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.view.endEditing(true)
if (searchBar.text?.count)! > 0 {
searchHandler(searchText: searchBar.text!)
}
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
searchBar.showsCancelButton = false
self.view.endEditing(true)
filteredValues?.removeAll() // this removes any previous array items
filteredValues = listValues // this assigns your listValues to filteredValues
collectionView?.reloadData() // this reloads your collectionView
}
func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (searchBar.text?.count)! > 0 {
searchHandler(searchText: searchBar.text!)
}
return true
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchHandler(searchText: searchText)
}
fileprivate func searchHandler(searchText: String) {
//implement your filtering here
}
}
Again, there are different ways you can implement your search filtering and assign your filtered values to the collectionView data source.
Hope this helps. Thanks
I want to just hide keyboard when user first press cancel button.
Just likes AppStore.app
I use UISearchController like that:
navigationItem.searchController = searchController
============== Update ==============
This Cancel button is hosted by UISearchController.
If you did search bar programmatically, you can add extension on your ViewController or else just use function call as below.
extension ViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if let text = searchBar.text {
self.filterContent(text: text)
searchBar.resignFirstResponder()
}
}
}
I try to make my searchbar on swift, but I have a problem to dismiss keyboard on screen when I pressed out of searchbar. When I try with textfield, it works perfectly fine with this code.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
It work when i press out of my textfield and then the keyboard is gone. I want to make like that with my searchbar, because when I use searchbar and use the same way like textfield, it doesn't work at all. Any reference or code is very useful for me.
try this :
self.mySearchController.searchBar.endEditing(true)
replace mySearchController with your created controller name..
If you did not create it programmatically but instead you just dragged a search bar from library then IBoutlet your searchable to your class and reference it as:
self.mySearchBar.endEditing(true)
I found it easier and simplier to use Table View for dismissal. (If you're using table view)
Swift 4:
self.tableView.keyboardDismissMode = .onDrag
Tested and working!
func searchBarSearchButtonClicked(searchBar: UISearchBar)
{
searchActive = false;
self.mySearchBar.endEditing(true)
}
Edit for Swift 4.2
func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
{
searchActive = false
self.searchBar.endEditing(true)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
searchProject.resignFirstResponder()
}
This method will be invoked when user click search button on keyboard.So here we can dismiss keyboard.I think this is the right method.
Firstly, Apple's UISearchBarDelegate is the correct solution to hide keyboard when users click a search button while UISearchBar's instance is the first responder (learn UIResponder). In short, searchBarSearchButtonClicked(_:) is what you need for this task.
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder() // hides the keyboard.
doThingsForSearching()
}
If it doesn't work, check, does your controller conform to UISearchBarDelegate and secondly, does UISearchBarDelegate know about your class implementation (if you don't quite understand what am I talking about, you should learn delegation pattern starting to read here):
class YourAwesomeViewController: UIViewController, UISearchBarDelegate { // pay attention here
#IBOutlet weak var yourSearchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
self.yourSearchBar.delegate = self // and it's important too
}
}
Further, if you need to hide the keyboard touching outside of search bar without touching the search button (the user may change his mind to search something), UITapGestureRecognizer is a simple way too to deal with that.
Ctrl-drag a Tap Gesture Recognizer from the Object Library to your View Controller.
Ctrl-drag the recently added Tap Gesture Recognizer from the document outline in the storyboard to your class implementation as IBAction.
Finally, write a code:
#IBAction func tapToHideKeyboard(_ sender: UITapGestureRecognizer) {
self.yourSearchBar.resignFirstResponder()
}
Also, don't forget to create #IBOutlet for the search bar to have an access inside your class implementation.
Both variants above work well in my project.
Swift 4+:
You can try, creating a tap gesture and add in the self.view
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(sender:)))
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.isEnabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(singleTapGestureRecognizer)
and in selector func you call self.searchBar.resignFirstResponder
#objc func singleTap(sender: UITapGestureRecognizer) {
self.searchBar.resignFirstResponder()
}
You can use a general UIViewController extension
Just add a new swift file on the project and paste the following code snippet
Code
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard(_:)))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
if let nav = self.navigationController {
nav.view.endEditing(true)
}
}
}
Now call hideKeyboardWhenTappedAround() from viewDidLoad method where you want keyboard hiding feature.
class MaCaveViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
}
// When button "Search" pressed
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
print("end searching --> Close Keyboard")
self.searchBar.endEditing(true)
}
}
This works very well for me.
we can do this with following methods
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchBar.showsCancelButton = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchBar.showsCancelButton = false;
}
This works for me in Swift 4
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
self.searchBar.endEditing(true)
}
I Swift, i make a Search View using UISearcheController and UISearcheResultUpdating
and i update the result with func updateSearchResultsForSearchController
if self.searchController?.searchBar.text.lengthOfBytesUsingEncoding(NSUTF32StringEncoding) > 0 {
let searchBarText = self.searchController!.searchBar.text
var arrResult = DFManager.GetResult(searchBarText)
self.results?.addObjectsFromArray(arrResult)
// Reload a table with results.
self.searchResultsController?.tableView.reloadData()
}
But that is result always updating when i type char by char, it make this app slowly. I want this result only update when type return key?
Try this:
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
//do something
searchBar.resignFirstResponder() //hide keyboard
}
And dont forget to add the searchBar delegate:
class SomeViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
searchBar.delegate = self
}
}
In Xcode4 I've created some placeholder text for a UITextField and I'd like it to clear when the user taps in the box.
So, in the Attributes Inspector for the text field I've clicked "Clear when editing begins" however this does not immediately remove the text when I tap in the text box (it only disappears when you start typing).
Is there any way of removing the placeholder text immediately on tapping in the text box?
make your ViewController the delegate of the textField and implement those two methods:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
textField.placeholder = nil;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
textField.placeholder = #"Your Placeholdertext";
}
The solution provided by Matthias Bauch works well, but what happens when you have more than one UITextField to worry about? Now you have to identify which UITextField is referred to in textFieldDidEndEditing:textField (possibly by use of the tag property), and that results in more unnecessary code and logic.
A much simpler solution: simply assign a clear color to the placeholder text , and when done editing, revert back to it's original color. This way, your textFieldDidEndEditing:textField doesn't have to identify the textField to set back its corresponding text after it was nullified as in Bauch's solution.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[textField setValue:[UIColor clearColor] forKeyPath:#"_placeholderLabel.textColor"];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[textField setValue:[UIColor placeholderColor] forKeyPath:#"_placeholderLabel.textColor"];
}
You should also check if text filed is empty then you should put place holder again
- (void)textFieldDidBeginEditing:(UITextField *)textField {
textField.placeholder = nil;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField.text isEqualToString:#""] || [[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0))
{
[textField setText:#""];
textField.placeholder = #"Your Placeholdertext";
}
}
use this..
- (void)textFieldDidBeginEditing:(UITextField *)textField{
textField.placeholder=nil;
}
don't forget to add the delegate for the textfield to your file Owner.
If you have more than one TextField
1) Add String variable to your class
class YourViewController : UIViewController {
var placeHolder = ""
2) Add UITextFieldDelegate
extension YourViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
placeHolder = textField.placeholder ?? ""
textField.placeholder = ""
}
func textFieldDidEndEditing(_ textField: UITextField) {
if textField.placeholder == ""{
textField.placeholder = placeHolder
}
}
In your .h file declare a function like
-(IBAction)clear:(id)sender;
attach this function to your touchdown event of your UITextField.
in your .m file
-(IBAction)clear:(id)sender
{
myplaceHolderText.text=#"";
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
textField.placeholder=nil;
}
textfield delegate make place holder value to nil
The #etayluz 's solution is better (my opinion), because you don't need to worry about assigning placeholder'a text again.
If you have custom textFields in different places of your app and want them to behave equally (as I need in my case) you can add this code to your custom TextField's class:
class CustomTextField: UITextField, UITextFieldDelegate {
private func setup() {
//do additional setup like attributedPlaceholder, inset, etc.
self.delegate = self
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
// MARK: UITextFieldDelegate methods
func textFieldDidBeginEditing(textField: UITextField) {
textField.setValue(UIColor.clearColor(), forKeyPath: "_placeholderLabel.textColor")
}
func textFieldDidEndEditing(textField: UITextField) {
textField.setValue(UIColor.lightGrayColor(), forKeyPath: "_placeholderLabel.textColor")
}
}
But if you need to have specific UITextFieldDelegate's methods for individual textField you DO need to implement this logic for it individually:
class LoginViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var emailTextField: CustomTextField!
#IBOutlet weak var passwordTextField: CustomTextField!
override func viewDidLoad() {
super.viewDidLoad()
textFields = [emailTextField, passwordTextField]
for textField in textFields {
textField.delegate = self
}
// MARK: UITextFieldDelegate methods
func textFieldDidBeginEditing(textField: UITextField) {
textField.setValue(UIColor.clearColor(), forKeyPath: "_placeholderLabel.textColor")
}
func textFieldDidEndEditing(textField: UITextField) {
textField.setValue(UIColor.lightGrayColor(), forKeyPath: "_placeholderLabel.textColor")
}
}
In case of SWIFT 3 or later
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.placeholder = nil
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.placeholder = "Text Placeholder"
}
On Button action Event put this Code:
txtName.placeholder = #"";