Before I get asked, no this is not a duplicate. No other question addresses this that I found with a satisfying answer.
I have been working on some code to make a data interface and I didn't want to use a date picker.
This is the code I'm using to get the XX/XX/XX format:
extension OneCreateAccountViewController {
func textFieldDidChangeSelection(_ textField: UITextField) {
if textField.placeholder == "DD/MM/YY" {
if textField.text!.count >= 2 && textField.text!.count < 3 {
textField.text! = "\(textField.text!)/"
} else {
if textField.text!.count >= 5 && textField.text!.count < 6 {
textField.text! = "\(textField.text!)/"
} else {
if textField.text!.count >= 9 {
textField.text!.removeLast()
}
}
}
}
}
}
As you can see it is pretty barebones, but my issue is that once "/" is inserted, no matter what happens, you cannot remove using the return key. I want a specific else statement that would work something like "else - if the backspace is returned and the last character is "", delete that character."
please help me in SPECIFICALLY HAVING A CODE THAT REGISTERS THE RETURN KEY (even if it is a simple "if return is pressed, print ("Hi")" like answer.)
You will have a lot of trouble trying to do this with only textFieldDidChangeSelection
...
To answer your specific "CODE THAT REGISTERS THE RETURN KEY" question, implement textFieldShouldReturn
in your UITextFieldDelegate
:
extension OneCreateAccountViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("Enter key pressed")
// Handle Enter key processing here
return true
}
}
To detect Backspace, implement shouldChangeCharactersIn
:
extension OneCreateAccountViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.isEmpty {
print("Backspace detected")
// Handle any additional backspace processing here
}
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("Enter key pressed")
// Handle Enter key processing here
return true
}
}
Important note!! - that will fail due to a bug in the iOS simulators! It does work on an iOS 15.0
simulator, and I've seen notes that the bug is fixed in iOS 17.4
simulator.
For the simplest approach, handle each new input in shouldChangeCharactersIn
:
extension OneCreateAccountViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// get the current text from the text field
// set it to "" if the text field is empty
var theText = textField.text ?? ""
if string.isEmpty {
print("Backspace detected")
// if the text field is empty, just ignore
if theText.count == 0 {
return false
}
// remove the last character from the string
theText.removeLast()
// if the string was, for example, "12/1"
// it will now be "12/"
// so remove the trailing slash
if theText.last == "/" {
theText.removeLast()
}
// update the text field
textField.text = theText
// don't allow built-in processing
return false
}
// it wasn't backspace
// if it's not a digit, or we already have 8 characters ("nn/nn/nn"), discard the new input
if theText.count == 8 || !"0123456789".contains(string) {
return false
}
// if the current text is "nn" or "nn/nn"
// append a slash
if theText.count == 2 || theText.count == 5 {
theText += "/"
}
// append the new input
theText += string
// update the text field
textField.text = theText
// don't allow built-in processing
return false
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("Enter key pressed")
// Handle Enter key processing here
return true
}
}
Your task will be, however, rather more complex...
For example, suppose the user has typed 25/12/2
and moves the caret / insertion point:
What should happen if a 0
is typed? Or a backspace? Do you want to insert/delete where the caret is, reformat the slashes if necessary, maintain the caret location, and so on.
And what do you want to happen if the user types 98/76/54
?
Ideally (I expect) you will want to validate every "keystroke":
0
, 1
, 2
or 3
1-9
if first char is 0
0-9
if the first char is 1
or 2
0
or 1
if the first char is 3
0
or 1
1-9
if fourth char is 0
0
, 1
or 2
if the fourth char is 1
and so on.
Of course, if the user types 02/3
or 06/31
or 05/38
(etc), you'll also need to reject that last input.