call prepareforsegue after user finished editing uitextfield - ios

How do i pass the value of the text from the UITextField into another view controller. Currently, when I override the func prepareForSegue(), it is being called before the user finished editing the textfield, so the value passed is always null.

You have a couple of ways to go about this:
Directly access the text value of your TextField instead of your model, which sounds like it is updated after didFinishEditing
Instead of updating your model only on didFinishEditing you can update it every time the text changes by implementing internal func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool, and getting the new value with let newString = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)

Related

UITextField no callback when autocorrect changes text

I added a target with editingChanged to the UITextField like this:
self.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
But if you are typing and iOS suggests the autocorrect and you tap next to where you are typing in the UITextField, the suggestion gets placed into the UITextField, but I did not get notified by the editingChanged.
I had the same problem with the UITextView and managed to "fix" it by setting the delegate and overriding
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
So I tried doing the same with the UITextField and expected to get the same result. So I set the delegate and override
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
However, still no callback when the autocorrect gets applied.
As an example, this is the autocorrect I'm talking about:
If you click on the field next to the word you're typing right now, the autocorrect gets applied. But no callback.
Does anybody have a solution for this?
For anybody looking for a solution here. I don't have a solution. I kept the editingChanged and added editingDidEnd. And made sure I always called self.view.endEditing(true) before I accessed the data. Not the best solution, but for now the only one I got.

Calling textField:shouldReplaceCharactersInRange from a delegate method

I've built a custom on-screen keyboard where each key tap returns a String?. In my delegate method, I want to forward that text onto the UITextFieldDelegate method: func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
func valueWasSent(string: String?) {
// activeTextField is a UITextField?
guard let textField = activeTextField else { return }
let range = NSMakeRange(0, string!.count - 1)
textField(activeTextField!, shouldChangeCharactersIn: range, replacementString: string!)
}
The last line here isn't working, and throwing the error:
Cannot call value of non-function type 'UITextField'
Any idea how I can accomplish this? Thanks
Most likely you should not be calling that delegate method yourself. The shouldChangeCharactersIn is simply a check if the edit would be valid. Normally, UITextField calls it to ensure the proposed change will be valid or not. If not, the change is ignored. If so, then the text field's text is updated.
If you really do want to call it, then you need to call it on the delegate, not self. You need to check the return value. If it returns true then you should update the text field's text accordingly.
if textField.delegate?.textField(textField, shouldChangeCharactersIn: range, replacementString: string!) {
// update the text field's text
}
Also note that the range you pass to it should reflect the current selection in the text field. You are setting it to match the length of string. That's bad. If you want string to fully replace the current value, at least pass in a range that matches the current value of the text field, not of string.

Swift: Detecting iOS Keyboard text replacement in UITextField

iOS has a built-in functionality where user can set up text replacements in
Settings > General > Keyboards > Text Replacement
In my Swift iOS app's UITextField, I need to know when user used this text replacement so I can take appropriate action. My instinct was to use
func textField(tf: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
but interestingly, this function is not invoked on this kind of text replacement, are there any other ways to solve this?
I tested the shouldChangeCharactersInRange function in this setting and it does see the text expansion. I tested with:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
print(string.characters.count)
return true
}
You can watch the character count jump immediately after the text expansion.
Make sure your textField is hooked up with an IBOutlet and you have set the class as a delegate (textField.delegate = self in viewDidLoad).
Once you see this working you can of course identify text expansion and handle any way you wish.

Disable preview secure text entry UITextField

When an entry is made in into an UITextField, that has secure text entry enabled.
The last character that is input is given a short preview for a second or so.
I want to disable that as well. Thus, as soon as a character is entered the black dot appears without the preview.
This can be accomplished by configuring the field's UITextFieldDelegate like this:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
textField.text = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
return false
}

Swift: Disable or Clear Undo for a TextField

When selecting NumberPad for a TextField, the iPad displays a full keyboard, so I have created a function to simply remove all characters that are not numeric. However, if a Non-numeric key is pressed and then the user presses Undo on the keyboard, the App Crashes.
How do I disable the Undo function for the TextField or at least clear the Undo Stack?
The answer was simple in the end, I used undoManager removeAllActions, but instead of just needing:
undoManager?.removeAllActions()
as a line, I needed:
myTextField.undoManager?.removeAllActions()
I placed this in the DidChange Action for the TextField.
Add UITextFieldDelegate in your controller.
In your viewDidLoad() assign yourTextField.delegate = self. Than implement this method
public func textFieldShouldClear(textField: UITextField) -> Bool{
return false // This will disable clear button
}
Also for replacing text I would suggest use
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{//Your Logic Here
}

Resources