UITextField doesn't end editing when Button clicked( delegate textFieldDidEndEditing )
Within your ViewController
class, for each textfield, create an @IBOutlet property by Ctrl-dragging each text field from the storyboard to your code
@IBOutlet weak var textFieldFirst: UITextField!
@IBOutlet weak var textFieldSecond: UITextField!
Also create a private UITextField
property to hold the (possibly) current (/most recently used) text field.
private var currentTextField: UITextField?
Override the viewDidLoad
method of your UIViewController
subclass to initialize the delegates for the two "public" text field instances
override func viewDidLoad() {
super.viewDidLoad()
// Handle the user input in the text fields through delegate callbacks (and set tags)
textFieldFirst.delegate = self
textFieldFirst.tag = 1
textFieldSecond.delegate = self
textFieldSecond.tag = 2
}
Moreover, use the two textFieldShouldReturn(...)
and textFieldDidBeginEditing(...)
methods of the UITextFieldDelegate
to resign the (active) text fields status's as first responder and to update the currentTextField
reference, respectively.
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
currentTextField = textField
}
Finally, resign any possibly current text field as first responder, in case submit
is pressed in-middle-of editing
@IBAction func Submit(sender: UIButton) {
if let currentTextField = currentTextField {
currentTextField.resignFirstResponder()
}
print(firstName)
print(lastName)
}
With this, your view controller should work as intended.
To summarize: after the additions and modifications above, your ViewController
class should look like
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
// Properties
@IBOutlet weak var textFieldFirst: UITextField!
@IBOutlet weak var textFieldSecond: UITextField!
private var currentTextField: UITextField?
var firstName = ""
var lastName = ""
@IBOutlet var buttonUI: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
// Actions
@IBAction func Submit(sender: UIButton) {
if let currentTextField = currentTextField {
currentTextField.resignFirstResponder()
}
print(firstName)
print(lastName)
}
// viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
// handle the user input in the text fields through delegate callbacks
textFieldFirst.delegate = self
textFieldSecond.delegate = self
// tags
textFieldFirst.tag = 1
textFieldSecond.tag = 2
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
currentTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
switch textField.tag {
case 1:
firstName = textField.text!
print(firstName)
case 2:
lastName = textField.text!
print(lastName)
default: break
}
}
}
how to call method on textfieldDidEndEditing
Just Put Condition for your textfield
func textFieldDidEndEditing(textField: UITextField) {
if textField == txtEmail { // OR with Tag like textfield.tag == 45
emailVarification()
}
}
UITextField doesn't end editing in a UITableViewCell in Swift 4
Working but not as sleek as want it to be and also I was not capable to make IQKeyboardManager
works so I did use inputAccessoryView
.
custom cell:
import UIKit
protocol PortfolioCellDelegate {
func portfolioButtonPressed(didSelect coinCell: PortfolioCell)
func portfolioButtonPressed(coinCell:PortfolioCell, editingChangedInTextCell newValue:String)
}
class PortfolioCell: UITableViewCell, UITextFieldDelegate {
var delegate: PortfolioCellDelegate?
...
@IBAction func editCellPressed(_ sender: UIButton) {
textCell.becomeFirstResponder()
delegate?.portfolioButtonPressed(didSelect: self)
}
@IBAction func textCellValueChanged(_ sender: UITextField) {
if (sender.text?.isEmpty)! {
delegate?.portfolioButtonPressed(coinCell: self, editingChangedInTextCell: "XXX")
} else {
let text = sender.text
delegate?.portfolioButtonPressed(coinCell: self, editingChangedInTextCell: text!)
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.textCell.delegate = self
let flexiableSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneButtonAction))
let toolBar:UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: 35))
toolBar.barTintColor = UIColor(red:0.15, green:0.69, blue:0.75, alpha:1.0)
toolBar.tintColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.0)
toolBar.setItems([flexiableSpace, doneButton], animated: false)
textCell.inputAccessoryView = toolBar
textCell.keyboardType = UIKeyboardType.decimalPad
}
@objc func doneButtonAction() {
textCell.endEditing(true)
}
...
}
ViewController:
import UIKit
class PortfolioViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, PortfolioCellDelegate {
let getData = GetData()
...
override func viewDidLoad() {
super.viewDidLoad()
cellTableView.delegate = self
cellTableView.dataSource = self
cellTableView.register(UINib(nibName: "PortfolioCell", bundle: nil), forCellReuseIdentifier: "portfolioCell")
self.currencyControl.selectedSegmentIndex = MyVariables.currencyControlSelected
getData.delegate = self
timeStampLabel.text = MyVariables.timeStamp
}
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.cellTableView.reloadData()
self.currencyControl.selectedSegmentIndex = MyVariables.currencyControlSelected
self.timeStampLabel.text = MyVariables.timeStamp
}
//MARK: - tableView
/***************************************************************/
...
func portfolioButtonPressed(coinCell: PortfolioCell, editingChangedInTextCell newValue: String) {
let indexPath = self.cellTableView.indexPathForRow(at: coinCell.center)!
let selectedCell = cellTableView.cellForRow(at: indexPath) as! PortfolioCell
selectedCell.priceCell.isHidden = false
selectedCell.textCell.isHidden = true
if newValue != "XXX" {
let owned: Double = Double(newValue)!
MyVariables.dataArray[indexPath.row].ownedCell = owned
}
selectedCell.priceCell.isHidden = false
selectedCell.textCell.isHidden = true
self.cellTableView.reloadRows(at: [indexPath], with: .automatic)
}
func portfolioButtonPressed(didSelect coinCell: PortfolioCell) {
let indexPath = self.cellTableView.indexPathForRow(at: coinCell.center)!
let selectedCell = cellTableView.cellForRow(at: indexPath) as! PortfolioCell
selectedCell.priceCell.isHidden = true
selectedCell.textCell.isHidden = false
}
...
}
Call UITextField Editing Did Begin only once
Please set Delegate for your textfield
textFieldName.delegate = self
Tapping outside a UITextField to stop editing
So it seems your amountEntered(_:)
is called anytime amountEnteredTextField
ends editing. This is due to you setting it up as an IBAction
for the event .editingDidEnd
.
In hideKeyboard()
, you have set up a tap gesture on self.view
linked to dismissKeyboard()
that does view.endEditing(true)
.
This basically resigns any first responder; meaning amountEnteredTextField
editing ends and hence amountEntered(_:)
is called when you tap outside.
If you want to ensure amountEntered(_:)
is called only when the user taps on the keyboard's return key then you should modify your design a little bit as so:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
/*
Check to see which is the delegated textField.
Basically to do textField-specific logic.
Helps mostly if you have multiple textFields
*/
if textField == amountEnteredTextField {
amountEntered()
}
//resign textField
textField.resignFirstResponder()
return true
}
func amountEntered() {
if allowNewAmount, amountEnteredTextField.text != "" {
amountLabel.text = amountEnteredTextField.text
amountEnteredTextField.text = ""
}
}
How do you dismiss the keyboard when editing a UITextField
I set the delegate of the UITextField
to my ViewController
class.
In that class I implemented this method as following:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
iPhone: UITextField End Editing event doesn't hide keyboard
it hides the keyboard but not when I don't press done button and move
to another uitextfield where I don't need keyboard but PickerView.
The right way to handle this is to set the inputView
property for the field that uses a picker instead of the keyboard. Configure the picker as you need it (set up delegate, data source, etc.) and then set it as the field's inputView
. The system will handle hiding the keyboard and showing the picker view, or vice versa, as you move from one field to the next.
Can I trigger an action when a button is pressed while an edit is in progress?
Inside your button's action, add the following line of code (should be the first line of code in the function):
[self.view endEditing:TRUE];
Note that this will also call the textFieldDidEndEditing
function of the active text field. That being said, you may just want to have a button that dismisses the keyboard, and then the textFieldDidEndEditing
will save the data, like this:
-(IBAction)yourAction {
[self.view endEditing:TRUE];
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//Save your data
}
iOS: Textfield delegate, how to end edit automatically before processing a row move in a table view?
You can declare an instance variable, like :
UITextField * selectedTextField;
and change it in :
- (void)textFieldDidBeginEditing:(UITextField *)textField {
selectedTextField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
selectedTextField = nil;
}
And wherever you make an action that requires to resign the active textfield, add :
if (selectedTextField && [selectedTextField isFirstResponder])
[selectedTextField resignFirstResponder];
Related Topics
Use More Than One Firebase Database in Single App - Swift
How to Retrieve Image Stored in Firebase to Show It in View Image View
Get Latitude and Longitude Center of Google Map
Libmobilegestalt Mobilegestalt.C:890: Mgisdeviceoneoftype Is Not Supported on This Platform
Audiokit - How to Get Real Time Floatchanneldata from Microphone
Swift - Using Cgcontext to Draw with Finger
Swift, Parse.Com: How to Pass Data from Query
Cmpedometer Querypedometerdatafromdate Returns Error 103
Swift Spritekit Playing Audio in the Background
iOS Healthkit How to Save Heart Rate (Bpm) Values? Swift
Get Current Song Playing in Spotify on Iphone
Apple Push Notifications in Tvos
iOS with Parse. Pfuser.Currentuser() Not Getting Cached. Returns Nil After App Restart
App Groups Forsecurityapplicationgroupidentifier Returns Nil