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.
i have a UITableview that has unique cells,
each cell has it's own class and they have actions that i want to connect to my main UITableviewcontroller
I attach a protocol and open it in the tableviewcontroller
but it doesn't get read
how could I initialise it or what am I doing wrong ?
here is my cell class :
import UIKit
class AddFaxHeadlineTableViewCell: UITableViewCell {
var delegate: AddFaxHeadlineProtocol?
#IBOutlet weak var addButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func onAddFaxNumberPressed(_ sender: Any) {
delegate?.faxButtonPressed()
}
}
protocol AddFaxHeadlineProtocol{
func faxButtonPressed()
}
and in my tableviewcontroller I extend the protocol:
class SummaryMainTableViewController: UITableViewController, AddFaxHeadlineProtocol, AddEmailHeadlineProtocol {
but the function itself never gets read:
func faxButtonPressed() {
var indexToInsert = 0
for forIndex in 0..<sectionsData.count {
// render the tick mark each minute (60 times)
if (sectionsData[forIndex] == "addFaxHeadline") {
indexToInsert = forIndex + 1
}
}
sectionsData.insert("addNewFax", at: indexToInsert)
mainTableView.reloadData()
}
You need to call:
cell.delegate = self
In your cellForRowAtIndex method
This is the common mistake done in protocols and delegates to forget to call delegate.
Here are few examples you can check all have missing is calling delegate:-
Swift delegate beetween two VC without segue
Delegate seems to not be working, according to the console
How to present another view controller after dismiss from navigation controller in swift?
Another way to go inside the vc without protocols
let cell = ///
cell.addButton.tag = indexPath.row
cell.addButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
}
#objc func buttonTapped(_ sender:UIButton) {
print(sender.tag)
}
Check that you are doing this:
cell.delegate = self (It's required)
Then improve your line of code like below. Because you will not set delegate then by calling this delegate method directly will get crashed.
#IBAction func onAddFaxNumberPressed(_ sender: Any) {
if let delegateObject = delegate {
delegateObject.faxButtonPressed()
}
}
Second,
In this line, delegateObject.faxButtonPressed(), you will need to send some parameter to identify that will cell is clicked. So you can pass here button tag or you can pass cell also.
Added a pickerView using a UITextField.
I am trying to trigger the pickerView programmatically.
func myTypeDetector (textfield: UITextField) {
typeLabel.delegate = self
self.setType(textField: typeLabel)
}
override func viewDidLoad() {
super.viewDidLoad()
typeLabel.addTarget(self, action: #selector(NewSpeciesVC.myTypeDetector(textfield:)), for: UIControlEvents.touchUpInside)
}
I have found how to do this via UIButton
self.typeLabel.sendActions(for: .touchUpInside)
However, this is not working for the UITextField.
I would like to programmatically create the event with the TextField, or create the PickerView event using a UIButton.
Any suggestions?
I needed to do the same thing and figured it out:
self.typelabel.becomeFirstResponder()
I have a textfield in each cell of my tableview. I want to quit keyboard when users pressed on the return key. I tried:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
But it doesn't work and I can't seem to find a away to reference the textfield inside the cell of my tableview. Please help, thanks!
I assume that you have created IBOutlets of your textfield in your cell class.
Give your textfield delegate to self in cellForRow datasource method of UITableView
cell.yourTextField.delegate = self
You can give delegate form storyboard.
You should let your custom UITableViewCell class to confirms to UITextFieldDelegate:
class TableViewCell: UITableViewCell, UITextFieldDelegate {
// ...
}
In awakeFromNib you should your textfields delegate to the cell class:
override func awakeFromNib() {
// ...
textField.delegate = self
// ...
}
Finally, implement textFieldShouldReturn:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Hope that helped.
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)
}