Field of blocking during editing. (Swift - iOS) - ios

Requirement
I want to block a text field (UITextField) while another text is being entered in another text field.
Example
I have two text fields on a form. When typing in the first text field, the second text field is disabled (i.e. you can not even press it by touching), only when you finish editing the first text field, you can edit the second one.

You can add your textfield to an an array and use the Equatable protocol to compare the textfield in the DidBeginEditing func and "disable" other fields. But when you are done editing you need to turn all your textfields back on. Also make sure your class has UITextFieldDelegate in the declaration.
var textfields: [UITextField] = [textfield1,textfield2,textfieldn]
func textFieldDidBeginEditing(textField: UITextField) {
for field in textfields {
if textField != field {
field.enabled = false
}
}
}
func textFieldDidEndEditing(textField: UITextField) {
for field in textfields {
field.enabled = true
}
}

Related

Make UITextField clear content each time return key pressed

I'm learning Swift by making a times tables app, which simply creates random times tables and asks the user to type the answer in a UITextField.
I'd like the user to be able to tap the return key and have the text field clear their previous answer and have the keyboard remain in view. I've already set up the other behaviour I want, it's just I can't seem to find any similar questions to figure out how to clear, and do all this when there return key is tapped.
Here's the code I have so far, which works when dismissing the keyboard, and doesn't clear the field.
Many thanks!
#IBAction func answerTyped(_ sender: UITextField) {
/* Clear the text field*/
questionNumber += 1
attempted += 1
markQuestion(answer: answer)
newQuestion(awardLevel: currentLevel, questionNumber: questionNumber)
}
If you want the textField to be cleared on tapping return button you can use the textFieldShouldReturn delegate.
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //delegate method
textField.text = "" // Clears text
//Do other things that you want to do when user taps return button
return true
}
Note that this wont dismiss the textField like how you asked and usually users are used to dismissing their textField using return. So if you ask me this is not good UX. And you need to have a mechanism for the user to dismiss the keyboard if needed like tap outside to dismiss or something. So i hope you have that sorted out.
Your viewController should have implemented the UITextFieldDelegate for this method work.
class YourViewController: UITextFieldDelegate {
var textField: UITextField! //Using IBOutlet or whatever
func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
}
you will need to make something, likely your view controller containing this text field into a uitextfieldelegate, then add the necessary delegate functions.
I think the function you want is TextField:DidEndEditing:Reason https://developer.apple.com/documentation/uikit/uitextfielddelegate/2352220-textfielddidendediting
Or you can just use
func textFieldShouldReturn(_ textField: UITextField) -> Bool { //delegate method
textField.resignFirstResponder()
return true
}
which is called every time user hits the return key. You would need to add your logic to clear the contents before the returns.

Swift 4 - identifying only one text field as delegate for editingDidEnd etc

I've kept this question free of specific context because I'm sure it will be helpful for others :
I have 2 IB outlet text fields :
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
I want to be able to disable buttons on my page until both have been filled out properly so I'm using the following delegates in ViewDidLoad() (I have added TextFieldDelegate to my VC.)
override func viewDidLoad() {
textField1.delegate = self
textField2.delegate = self
}
I then have some functions I will use to do the form validation and to take specific actions but to keep it simple let's say it simply prints to the console.
What I want to do is only check for validation in textField1 and not in textField2. I.e. the desired output is that this prints for when user begins editing textField1 but if user edits textField2 nothing is printed.
I'm currently using :
func textFieldDidBeginEditing(_ textField1: UITextField) {
print("TextField did begin editing method called")
}
But that is printing when either textField is edited.
I thought I've specified _ textField1 so not sure why both are triggering it?
There are some answers solving similar problems for Swift 3 and earlier. In particular one answer referenced this link http://sourcefreeze.com/uitextfield-and-uitextfield-delegate-in-swift/ which i've found useful but am stuck on this error.
UITextField delegate method allows you to identify that which textField is begin editing so you just need to check whether it's your 1st textField or not like this.
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == self.textField1 {
print("TextField did begin editing method called")
// Do your Validate for first text field
} else {
//Do Nothing
}
}
That's why the delegate function textFieldDidBeginEditing has a textField parameter. Renaming it does nothing.
If you want to discern your text fields, compare the textField parameter to your IBOutlets, like so:
func textFieldDidBeginEditing(_ text Field: UITextField) {
if textField == textField1 {
// Validate first text field
} else if textField == textField2 {
// Validate second text field
}
}
simply set tag for both textFields as 0 and 1 then in your delegate method just check the tag of your textfield.
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.tag == 0 {
print("TextField did begin editing method called for text field 1")
}
}
Let's first analyse your piece of code and see what is wrong:
func textFieldDidBeginEditing(_ textField1: UITextField) {
print("TextField did begin editing method called")
}
You renamed textField to textField1. However, that does not name the UI element that should be responsible for this action. Instead, that is a function parameter which lets you access information about the object that called the action from within your function, regardless of the outer scope. Instead, you should use the === operator, which checks whether two references point to the same object instance. So your code should become:
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField === self.textField1 {
print("TextField 1 did begin editing method called")
}
}
You have named the parameter that receives the UITextField reference that is passed to the delegate method textField1; the name of this parameter is nothing to do with the name of your property. You could have called it textField and your code would still compile, despite not having a property called textField.
You need to compare the instance of UITextField that was passed to the delegate method:
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField === self.textField1 {
print("TextField did begin editing method called for text field 1")
}
}
you can do both ways either you can put if condition on textfield like paul said or if you don't want textfield2 to work with any of the textfield delegate you can remove the line
textField2.delegate = self

How do I erase text from UITextField upon user touch in Swift 3?

I have a UITextField that holds the text: "Username". I want to erase the user name once the user has selected the text field for editing.
Is there a better way than using the selector method?
Here is the method I'm currently using, but it doesn't seem to be working.
usernameTextField.addTarget(self, action: #selector(selectedUsernameField), for: .editingChanged)
func selectedUsernameField(sender: UITextField){
print("selectedUsernameField")
usernameTextField.text = ""
}
I this case you should set the placeholder for usernameTextField.
usernameTextField.placeholder = "UserName"
It will disappear as user will start typing that's what you want.
You can use this function:
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == usernameTextField{
textField.text = ""
}
}
It is called when the text field begins editing.
Although to use it you will need to make your class a UITextFieldDelegate
and also say:
usernameTextField.delegate = self
in viewDidLoad.

Hiding a UIButton when a text field is clicked on Swift

New to Swift and making a simple to-do app.
I am trying to get it so that when a UI TextField is clicked on, a certain button should be hidden. It's only when the user presses enter after typing in a task that the button should appear.
I have an IBAction set up for my text field to hide the UIButton when it is clicked on like so, but it doesn't work:
#IBAction func textFieldClicked(_ sender: Any) {
self.cellButton.isHidden = true
}
And I have set up my textfieldshouldreturn function when the user presses enter like so:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.cellButton.isHidden = false
self.cellButton.isUserInteractionEnabled = true
textField.resignFirstResponder()
return true
}
Does an IBAction for text field only respond when enter is pressed? I tried messing with flags but that didn't work either.
Any help is appreciated.
You don't need an IBAction for this. Instead, implement another UITextFieldDelegate method - textFieldDidBeginEditing.
func textFieldDidBeginEditing(_ textField: UITextField) {
self.cellButton.isHidden = true
}
This delegate is called when a text field becomes the first responder.
On a slightly unrelated note, it's best to return false instead of true from your textFieldShouldReturn method.
Please, use delegates method textFieldDidDeginEditing and hide button.

UITextField with user text + static mark

I have an UITextField which user sets its luggage weight as numbers in TextField. I want to set that textfields value with weight mark (for ex 10 KG which comes from user settings) so whatever user types, there will be KG mark at the end of its textfield. Is there any way for it?
do like
initially clear the value when begin start
func textFieldShouldBeginEditing(textField: UITextField) {
textField.text = ""
}
when editing is over append the kg
func textFieldDidEndEditing(textField: UITextField) {
yourTextfieldName.text = "\(textField.text!) KG"
}
Choice-2
func textFieldDidEndEditing(textField: UITextField)
{
if !textField.text!.rangeOfString("KG").location != NSNotFound {
self.textField.text = textField.text!.stringByAppendingString("KG")
}
}
You could place a "Label" next to the UITextField.
And then just change the text of the Label to whatever the user selects.
OR (but i dont know if that works), try to get the text form the textfield, add the unit (as a string) to the string from the textfield.

Resources