I have a UIViewController which has 3 three UITextFields - TF1, TF2 and TF3. When the app is running on iOS simulator and I press Tab key, the focus moves to the next text field as expected.
TF3 is special. When the user taps on TF3, the text field should not get focused but instead a new view must be shown on the screen. I have implemented the UITextFieldDelegate method textFieldShouldBeginEditing(_:) to fix this as follows-
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if (textField == TF3) {
// show new view
return false
}
return true
}
This works as expected.
After the above code is added, whenever the Tab key is pressed, the new view is shown. This is because whenever the Tab key is pressed, textFieldShouldBeginEditing(_:) is called on all the text fields on the screen.
Consider that TF1 is the first responder at present.
If I press Tab key, it moves the focus to TF2 as expected. However, the new view is also shown because textFieldShouldBeginEditing(_:) is called on TF3.
Can anyone point out how to solve this issue?
if I understand you correctly,what you want is below:
Plan A
var isTF3Beginned = false // a property of current view controller as flag
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if (textField == TF3 && isTF3Beginned == true) {
// show new view
return false
}
isTF3Beginned = true
return true
}
Plan B RxSwift
TF3.rx
.controlEvent(.editingDidBegin)
.skip(1)
.subscribe(onNext: { () in
// show new view
}).disposed(by: disposeBag)
Related
I am using swift in a storyboad application, and I would like it to, when a user enters the box (IE, when it becomes the first responder) to enter text it highlights all the text. What is done in most web browsers. Here is what I have tried, which has not worked:
func textFieldDidBeginEditing(_ textField: UITextField) {
// textField.selectAll(nil)
print("click 2")
// textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
print("click 1")
// textField.selectAll(nil)
// textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
return true
}
Making a button that runs this code does actually work, but I want it to be when you click on the field. Making an invisible button on top seems like a bad idea. I've tried other variations of this as well, but none have worked for me.
UPDATE: What I've ended up doing was making an invisible button on top of the existing text field, and then making that select the text. It may be a little janky but it works perfectly so I have no problems with that solution anymore. Extra code:
#IBAction func seachBtnClicked(_ sender: Any) {
//The invisible button over the search bar has been clicked
search.selectAll(nil)
searchBtn.isHidden = true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//Return has been pressed, so we are going to load a new page
processInput()
//This does mean that it only comes back if you press enter,
//but right now I think that's how I want it.
//Could change it to be in the textFieldDidEndEditing() function to change that
searchBtn.isHidden = false
return true
}
You are probably just missing the textField.delegate = self for your textfield. The first of the two functions, func textFieldDidBeginEditing(_ textField: UITextField) is the one that is always performed as soon as a textfield is tapped on to focus on it.
Try adding yourTextField.delegate = self in your viewDidLoad function and see if that works out.
What I've ended up doing was making an invisible button on top of the existing text field, and then making that select the text. It may be a little janky but it works perfectly so I have no problems with that solution anymore. Extra code:
#IBAction func seachBtnClicked(_ sender: Any) {
//The invisible button over the search bar has been clicked
search.selectAll(nil)
searchBtn.isHidden = true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//Return has been pressed, so we are going to load a new page
processInput()
//This does mean that it only comes back if you press enter,
//but right now I think that's how I want it.
//Could change it to be in the textFieldDidEndEditing() function to change that
searchBtn.isHidden = false
return true
}
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.
I want to hide the keyboard every time a user click on the textField named typeDeProbleme. So, I did something like below (in the if condition) which in my understanding should've work but unfortunately it's not. Every time I click on the typeDeProbleme, the keyboard is stuck and cannot be hidden unless I click on another textField. For your information, typeDeProbleme is a textField linked to a PickerView. I also attached a toolbar on top of my keyboard that have a button X to hide the keyboard. Can anyone explain to me where is the problem?
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.returnKeyType = .next
if textField == self.typeDeProbleme {
textField.endEditing(true)// hide keyboard
textField.resignFirstResponder() //hide keyboard
self.pbTypePickerV.isHidden = false
}else{
keyboardDidShow(vvv: textField)
}
}
Use this method instead textFieldDidBeginEditing
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == typeDeProbleme {
self.view.endEditing(true)
return false
}
return true
}
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.
I have a ViewController set as a delegate for a UITextField. No matter what I try, I can not get the keyboard to hide when calling textFieldShouldReturn.
My viewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(newModelField)
newModelField.delegate = self
self.presetTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "presetCell")
//self.view.becomeFirstResponder()
}
and my textFieldShouldReturn method:
func textFieldShouldReturn(textField: UITextField) -> Bool {
//UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)
if(textField.text! != ""){
items.append(textField.text!)
presetTableView.reloadData()
textField.text! = ""
//self.view.resignFirstResponder()
//self.addView.resignFirstResponder()
//textField.endEditing(true)
//self.view.endEditing(true)
UIApplication.sharedApplication().delegate?.window?!.endEditing(true)
return false
}
return true
}
You can see from my commented out attempts that I have tried a whole host of different fixes. I know that textFieldShouldReturn is being called after debugging with print statements. I can not figure out why the keyboard won't hide.
I tried swapping the return true and false statements. I tried setting the delegate from the storyboard. I tried deleting the textField from storyboard, cleaning, and adding it back in. I tried all top level calls to resignFirstResponder and endEditing as well as calls to these functions for the textfield and the view.
To dismiss the keyboard, send the resignFirstResponder message to the text >field that is currently the first responder. Doing so causes the text >field object to end the current editing session (with the delegate >object’s consent) and hide the keyboard.
yourTextField.resignFirstResponder()
I tried using resignFirstResponder() on textFiled and also used endEditing(true) on my view but I did this small mistake of implementing this other delegate and was returning false
func textFieldShouldEndEditing(textField: UITextField) -> Bool { //delegate method
return true
}