Enabling a specific UITextField if another UITextField has a certain value - ios

I have two UITextFields, cDiseasePicker and optionalLMS.
My cDiseasePicker uses a UIPickerView as input, with the options "No", "Yes, 1VD", "Yes, 2VD", and "Yes, 3VD".
If the user chooses "No", then optionalLMS should be greyed out/user interaction disabled. Otherwise, they should be allowed to edit it.
I've tried adding
func textFieldDidEndEditing(_ textField: UITextField) {
if cDiseasePicker.text == "Yes, 1VD" || cDiseasePicker.text == "Yes, 2VD" || cDiseasePicker.text == "Yes, 3VD" {
optionalLMSText.isUserInteractionEnabled = true
print("true cdisease")
} else if cDiseasePicker.text == "No" {
optionalLMSText.isUserInteractionEnabled = false
print("false cdisease")
}
}
But this seems to have no effect, and nothing is printed to the console.
This is my class declaration, if that makes a difference:
class NewRecord: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate
Apologies if this is a basic question, I'm still fairly new to Swift.

As you're using a UIPickerView as input, you should look at your picker view didSelectRow (which I guess you are using to populate your cDiseasePicker textfield) to configure the other textfield to your liking.
If I understand correctly the key information you need is that textFieldDidEndEditing method is called when the text field is no longer the first responder, not when the text changes.

Related

UITextField change in iOS for conversions

I am creating a conversion application. I have multiple text fields. What I intend to do is when I start entering Kg value its equivalent gram and pound value should be displayed in the gram and pound text fields. How can it be done using editingChanged function in iOS?
This question is very broad but I will try to give a short answer of how to track changed of text fields:
class YourViewController: UIViewController {
#IBOutlet weak var textField: UITextField!
#IBAction func textFieldDidChange(_ sender: UITextField) {
self.textField.text = doSomeCalculation(sender.text)
}
}
First, you need to set up a view controller (or a view or whatever suits your interface design) with a UITextField. Then you connect the UITextField with the variable textField and the desired action of the text field with the function textFieldDidChange. You can use the action Editing Changed but I prefer Value Changed (depends on what you want to achieve).
Any time the text field is changed the function textFieldDidChange is called and you can do your calculations and alter the text of textField.

How to disable UIControlEventEditingChanged

I have a UIViewController with several UITextFields. When tap one text field, it should present the barcode scanning view controller. Once the scanning is completed, my barcode scanning viewcontroller is disappearing (used "dismissViewcontroller") and the scanned value should entered into the text field I tapped. This is working fine. I have set the delegate for each text field like this.
[field addTarget:metrixUIViewControllerIn action:#selector(executeScriptOnTextFieldChange:) forControlEvents:UIControlEventEditingChanged];
The problem is this :
Lets say I have set an alert to display inside this executeScriptOnTextFieldChange method. Once I tapped on the 1st text field, then the barcode scanner comes. Once I scanned barcode scanner closes and set the value for the first text field and fire the alert.Thats ok. But then if scanned by tapping the 2nd textfield and the string will set to that textfield and fire the alert related to 2nd textfield also fire the alert related to first textfield as well. I want to stop happening this. Is there any way to disable the delegate for one textfield? This happens because I am refreshing the view in the viewDidAppear. But I have to do that as well. Please help me.
UIControlEventEditingChanged for a textField can fire at many different events that are not even directly related to that textField, but related inderectly.
For instance, when your ViewController is presenting the barcodeScanner it may trigger a "resignFirstResponder" event on the textField. Also when the 2nd textField is tapped, cause the 2nd becomes first responder and the 1st suffers a "resignFirstResponder".
I suggest trying to use a UITapGestureRecognizer in your textField instead. Example:
Swift 4
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.textField.tag = 1
self.textField.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(fireTextField(_:))))
}
#objc func fireTextField(_ sender: UIGestureRecognizer){
let view = sender.view
guard view != nil else{
//Do nothing
return
}
let condition = view!.tag == 1
if condition{
//or do whatever other stuff you need
self.textField.becomeFirstResponder()
}else{
//Whatever for other textFields
}
}
This way, you could use the "tag" attribute to determine which textField is firing and so adjust "condition". You could also filter the flow with a switch using the "tag".
Not sure if any of this will really help as I would need more info about the flow you need to accomplish. Hope it does help!

How to move one text field to another using keyboard return key in swift3 ios

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.

How to unclear UITextField secure text entry in Swift?

When I use default Security text Entry in UITextField in Swift Language after type type text once UITextField.
Once loss focus from UITextField after try to edit Secure text then UITextField is first reset and after it start put new text in UITextField.
How to edit old Secure Text without Storing data into Any Kind of String object
I'd suggest to create a custom UITextField class and override become​First​Responder() method do add your desired functionality:
You can override this method in your custom responders to update your
object's state or perform some action such as highlighting the
selection. If you override this method, you must call super at some
point in your implementation.
The custom Class should be similar to:
class CustomSecureTextField: UITextField {
override func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true }
if let currentText = text { insertText(currentText) }
return true
}
}
The logic of the implementation of becomeFirstResponder as follows:
By default, the secured-entry text field clears the inserted text when it is become first responder text, so what's happening in CustomSecureTextField that if the text field is secured-entry, it will re-insert the current inserted text -after clearing it-, but you have to make sure that the text field input is secured (that's the purpose of adding if !isSecureTextEntry { return true }) or the text will be duplicated (re-inserted) each time the text field becomes first responder.
Output:
Note that both of text fields are types of CustomSecureTextField:
This answer helped me to figure out this problem.
textField.isSecureTextEntry = true
following property not gonna work if you make testField isSecureTextEntrysecure property makes true .
textField.clearsOnBeginEditing = false
There is an issue with the #Ahmd F solution when you simply tap on the field it will automatically add the text to the field I have resolved that in the below code thanks
override open func becomeFirstResponder() -> Bool {
super.becomeFirstResponder()
if !isSecureTextEntry { return true}
if let currrentText = text {
self.text = ""
insertText(currrentText)
}
return true
}

Why call method to resignFirstResponder from textFieldShouldBeginEditing?

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.

Resources