I am trying to understand delegate methods in general, and specifically how to dismiss a UIDatePicker that popovers from a text field.
According to the documentation, textFeildShouldBeginEditing returns true 'if an editing session should be initiated; otherwise, false to disallow editing.'
Why would I then tell the app to resignFirstResponder, which is meant to hide the keyboard / date picker (as in several examples on stackoverflow and noobie tutorials)?
What I don't understand is: if it should begin editing, why then hide the input devise? Obviously, I am misunderstanding one or both concepts.
func resign() {
dobTextField.resignFirstResponder()
nameTextField.resignFirstResponder()
println("resign gets printed, but the date picker is still visible!?!")
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if (textField === dobTextField) {
resign() // but should begin editing, oder?!?
}
In the examples you cite, the textField is being used to display a date. When the user selects this field, the app designers want the UIDatePicker to be displayed instead of the keyboard. Hence they call resignFirstResponder to hide the keyboard. At the same time, they display the date picker.
ResignFirstResponder will not hide the date picker, so the "input device" (for this field) will still be available.
Also, note that in one case the developer has used textFieldShouldBeginEditing, and returns false because they are providing the date picker. In the other case the developer uses textFieldDidBeginEditing (which has no return value).
you should resign only the textfield not affected:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if textField == dobTextField {
nameTextField.resignFirstResponder()
} else if textField == nameTextField {
dobTextField.resignFirstResponder()
}
return true
}
this way you are resiging first responder only on the textfields that should not currently be edited. this helps if for some reason you accidentally have 2 textfields (or more) assigned first responder causing conflicts with multiple keyboards/datepickers and such.
Related
By this img with done btn to move at next textfield (https://i.stack.imgur.com/cDHlh.jpg)
I doubt if you can do that with the 'Done' button, but you may achieve that with the return key by
Make your class a UITextField Delegate
class VC: UIVIewController, UITextFieldDelegate
In your ViewDidLoad method do this -
textField1.becomeFirstResponder()
So that when user comes in this screen the 1st textfield will directly become active(not the right word but using this word for lack of better alternative)
And when you need it to move to the next textfield when he presses return,
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField1.resignFirstResponder()
if (textField == textField1){
textField2.becomeFirstResponder()
}
else if (textField == textField2){
textField3.becomeFirstResponder()
}
return true
}
You may use a switch case too in the above delegate method. And as mentioned in the comment in the question, do go through the link and know how to properly ask questions, giving as much detail as possible.
I have a UITextField that can be set into editing mode.
Normally, editing is ended by entering „Done“ on the keyboard.
This calls textFieldDidEndEditing(_ textField: UITextField), where some housekeeping happens.
In rare cases, however, an alert is shown that the user entered a geofence. If the text field is then in editing mode, it resigns first responder status since the alert view becomes first responder, and textFieldDidEndEditing(_ textField: UITextField) is also called. When the alert is dismissed, the first responder status of the text field is restored.
The problem:
I have to distinguish both cases:
If the text field ends editing because of a Done on the keyboard, housekeeping should happen.
If it ends editing because an alert was shown, housekeeping must not be done.
So, how can I distinguish both cases?
I tried to use the delegate function
textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason)
where reason may be cancelled or committed, both in both cases the reason is committed.
You could use textFieldShouldEndEditing and assuming you can identify that the geofence has been triggered, return false, which will leave the textField in edit mode, otherwise return true, and the housekeeping can begin
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool
{
// assuming you take the same action for all TextFields
// assume geoFenceHasBeenTriggered is a class-variable true / false
return !geoFenceHasBeenTriggered
}
Evening, in my app I have several UITextfield. Each one has to confirm to different limitations.
For example, I have a date Field, zipCode Field, SSN Field etc.
From the Apple Documentation I found:
Assign a delegate object to handle important tasks, such as:
Determining whether the user should be allowed to edit the text field’s contents.
Validating the text entered by the user.
Responding to taps in the keyboard’s return button.
Forwarding the user-entered text to other parts of your app.
Store a reference to the text field in one of your controller objects.
So I'm pretty sure I have to use delegates and func textFieldDidEndEditing(_:).
The only way that came to my mind is to use a switch statement inside the func textFieldDidEndEditing(_:) to confirm the delegate to the difference limitation.
Is there a better, safer and faster pattern to face this problem?
You can set unique tag to your every text field and can compare in textFieldDidEndEditing or you can take IBOutlet of every textField and can compare it in textFieldDidEndEditing like,
func textFieldDidEndEditing(textField: UITextField) {
// By tag
if textField.tag == 100 {
}
// OR
//by outlet
if textField == self.myTextField {
}
}
You are right, you will have to check the textfield, either you can check tags assigned for different text fields using switch statement like you said,
or you can compare textfields itself,
if textfield1,textfield2 are outlets to two text fields, you can compare as following,
func textFieldDidEndEditing(textField: UITextField)
{
if textField == textfield1
{
}
else if textField == textfield2
{
}
}
you can create enum for validation
enum Type {
case zipcode
case number
}
then you can create a method for validation like this :
func isValidate(text: String, type: Type) -> Bool {
switch type {
case .zipcode:
...
}
}
this method can be in Util class. this is best practice. because your logic is encapsulate from out .
If you need more control over the text which is committed to the text field or if you want to provide feedback while the text field is being edited, you should implement a different delegate instead:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// Build and check the new text value. Accept or reject the change.
}
In the delegate, you can build the new text value. Validate it, apply constraints, decide on which feedback the user should receive ("Your password must be at least eight characters long", "This is not a valid IBAN"), accept or reject the change (i.e. return false).
Keep in mind, that the delegate is not called if you assign the text property manually. Moreover, this delegate is called when text is pasted into or deleted from the text field, which can make matters much more complicated depending on what you do.
I was searching for hiding the iOS keyboard when you press "return", and about half the answers are to use self.view.endEditing(true) and the other half textField.resignFirstResponder(). Is one a better way than the other?
For reference or anyone coming here from Google or something, you need to add UITextFieldDelegate to your class inheritance, add self.<your_TF_var_name>.delegate = self in viewDidLoad(), then make a function
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.view.endEditing(true)
return false
//OR
textField.resignFirstResponder()
return true
In this case, it doesn't really matter which you use though technically, using textField.resignFirstResponder() is more efficient because you already know that is the text field you need to resign.
The call to self.view.endEditing(true) is going to have to figure out what the current first responder is and then call resignFirstResponder on it.
My general rule of thumb is to use resignFirstResponder if you have a reference to a specific view you wish to resign. And use endEditing if you don't and you just want the current first responder to be resigned.
On a side note, you should return false from textFieldShouldReturn in either case. There is an edge case where returning true can lead to a newline being added to a UITextView after resigning the UITextField. So as a rule I always return false.
I am hiding keyboard on return key pressed by implementing function textFieldShouldReturn and calling resignFirstResponder() inside this function. It works perfectly but when I return false in this function, still then keyboard is hiding. Now here I do not understand that what is use of returning true or false if keyboard is hiding in both case?
The keyboard is being dismissed due to the call to resignFirstResponder. It has nothing at all to do with the return value of textFieldShouldReturn.
In my experience, the return value of textFieldShouldReturn almost has no use. In the vast majority of cases it makes no difference whether you return true, or false.
I return false in all my uses of testFieldShouldReturn. If you return true and your implementation of textFieldShouldReturn sets the first responder to a UITextView, the text view ends up getting the newline added to it. Returning false from textFieldShouldReturn ensures this won't happen. But this was based on experience with iOS 4 or 5 a few years ago. I don't know if that still happens with the latest versions of iOS.
The return value from textFieldShouldReturn answers a different question. If the text field has an action for the control event editingDidEndOnExit, that will cause the keyboard to dismiss unless textFieldShouldReturn is implemented to return false.
I have tried that wether true or false, the keyboard do dismiss, here is the code:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
The keyboard do dismiss or not depends on "textField.resignFirstResponder()",
if you delete it, the keyboard does no longer dismiss, whether true or false.
It's been a long time since I worked on Native iOS. Nearly 2 years. I've just picked up swift 5 and working through the forgotten and new parts right from the basics. Here's what i have observed.
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
if searchTextField.text != "" {
return true
}
searchTextField.placeholder = "Type Something"
return false
}
Here when I press the return key without typing a single letter in it, Keyboard does not dismiss. Rather the placeholder text changes to notify user to type something. The magic of returning false from textFieldShouldEndEditing.
If I press the same return key after entering at the very least a single character, it simply dismisses the keyboard. Courtesy of returning a true from the same textFieldShouldEndEditing.
I also didn't observe any difference when I placed textField.resignFirstResponder() regardless if I return true or false.
Conclusion:
true dismisses the keyboard. false stops the keyboard from dismissiong.