Keyboard not being dismissed - swift

I realize this is a trivial question with tons of answer on SO. I may just need a pair of fresh eyes as I've triple checked everything and cannot see where I am going wrong with this. I just want to dismiss the keyboard on hitting the return key. I'm setting the delegate properly and implementing the proper methods, so why won't the keyboard dismiss?
Does having a collectionView in the viewController complicate things? (text field is NOT inside collectionView)
class SearchController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITextFieldDelegate {
#IBOutlet weak var searchBar: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
setupUI()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
searchBar.resignFirstResponder()
return true
}
Things I've tried:
cleaning the project
restarting xcode
changing the searchBar.resignFirstResponder() to textField.resignFirstResponder()
setting the delegate for the text field inside IB instead of in viewDidLoad
What the heck am i missing here!?

You need to implement the proper text field delegate method. There is no such delegate method as textFieldShouldReturn(textField:). The proper method is textFieldShouldReturn(_:).
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchBar.resignFirstResponder()
return false
}
The _ makes a huge difference. You may have copied an old Swift 2 implementation.
It's best to let Xcode perform code completion to ensure you get the correct signature of any method you are implementing or calling.

Use this code
view.endEditing(true)

Related

Best way to handle textViewChanged in Swift 5.5

I'm trying to add attributed strings to some text in a UITextView on text change in Swift 5.5
What's the best approach, a UIView or a UIViewController?
Sample code would really help me out as I can't seem to get either approach to work atm.
Thanks
class ViewController: UIViewController, UITextViewDelegate { //If your class is not conforms to the UITextViewDelegate protocol you will not be able to set it as delegate to UITextView
#IBOutlet weak var bodyText: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
bodyText.delegate = self //Without setting the delegate you won't be able to track UITextView events
}
func textViewDidChange(_ textView: UITextView) { //Handle the text changes here
print(textView.text); //the textView parameter is the textView where text was changed
}
}
#Rob Hope this boilerplate works for you :)

Keyboard does not resign from view

I have a search bar in my app. The search bar is connected via a delegate to the main view controller. Even with textFieldShouldReturn and searchBarSearchButtonClicked nothing is happening.
I have tried to reconnect the delegate, and set the searchbar.delegate as self in my code (Results in a crash)
func searchBarSearchButtonClicked( _ searchBar: UISearchBar!){
print("Testing")
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
view.endEditing(true)
return true
}
You need to add UISearchBarDelegate in your class ViewController.

Dismiss keyboard for textfield in uitableviewcell in tableviewcontroller - Swift

I have a textfield and textview in my custom tableviewcell.
I have 4 different prototype cell with 4 different class created. there is a textfield in 1 prototype cell and a textview in the other.
I am not sure how I can do it and I dont understand the obj-c answers out there.
I've tried
override func viewDidLoad() {
super.viewDidLoad()
let tap: UIGestureRecognizer = UIGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
view.addGestureRecognizer(tap) }
and
func dismissKeyboard() {
self.view.endEditing(true)
}
I wanted to try
UITextFieldDelegate and touchesbegan and textfieldshouldreturn method, but there are no textfields to call in my tableviewcontroller.
Go to attributes inspector in storyboard and click tableView and set keyboard to dismiss interactively.
Or
Set textField delegate and implement
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return false to ignore.
{
textField.resignFirstResponder()
return true
}
I had same problem, you can solve this with IQKeyboardManager, you don't need to complicate things with the custom cell classes, just install it on your project, when you're all set with installation, in the appDelegate inside the didFinishLaunchingWithOptions method, add this line of code:
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
Get IQKeyboardManager from here.

How to make keyboard dismiss when I press out of searchbar on Swift?

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)
}

Is there any way to make UITextFieldDelegate more dynamic in swift?

I nearly have a UITextFieldDelegate in a UIViewController,and I make
import UIKit
class testViewController: UIViewController,UITextFieldDelegate{
#IBOutlet weak var textName: UITextField!
override func viewDidLoad(){
super.viewDidLoad()
textName.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
return true
}
}
it works very well.
but my question is, when i have two, or three UITextFields, and have different function,what should i do? Is there any way to make UITextFieldDelegate more dynamic in swift? just like java do? I remember that java may do like that:
textName.delegate = UITextFieldDelegate{
func textFieldShouldReturn(textField: UITextField) -> Bool {
return true
}
}
textAddress.delegate = UITextFieldDelegate{
func textFieldShouldReturn(textField: UITextField) -> Bool {
return true
}
}
The delegate methods take a parameter that identifies the text field for which the demarcate methods are being called. You can use this to provide different behaviours for different text fields.