0

I'm trying to pass the value in my textfield to another view using delegates. This is how I tried to achieve that..

In the 2nd view from where the value is to be passed to main view, this is what I have written..

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if let _ = raDelegate {
        raDelegate?.durationChanged(hrs: string)
    }
    return true
}

And in the first view, this is what I have...

 func durationChanged(hrs: String) {

        myView.durationTextField.text = hrs
  }

Now the issue is that if I type in say "5" in the textfield, in the durationChanged function, on applying breakpoint, I get the value in hrs as "5" itself. But when I remove the breakpoint and run, then what gets finally printed to myView.durationTextField.text is 55. Also if I print "7" after that, the "55" gets replaced by "77". While ideally what I should have got was "57".

user987654
  • 19
  • 5
  • https://stackoverflow.com/questions/28394933/how-do-i-check-when-a-uitextfield-changes ? You have a "shouldChange", you see the "should", so it's not full yet. Print the `string` and print `textField.text`, you should see the difference. – Larme Jun 17 '20 at 10:03
  • Ok @Larme..sure.. – user987654 Jun 17 '20 at 10:07
  • I tried what you suggested @Larme and wrote this...`raDelegate?.durationChanged(hrs: textField.text ?? "")`. This time it properly prints the numbers I enter. But if I do `print(myView.durationTextField.text)` then I get the previous number printed always i.e. if I enter '5', the printing gives me "", and if I go on and enter '56', the printing gives me '5' and if I again continue to enter '567', the printing gives me '56' and so on... – user987654 Jun 17 '20 at 10:19

2 Answers2

0

you use it wrongly. string on shouldChangeCharactersIn function isn't the value of textField.

for example: 1. textField.text = "" 2. input 5 -> range is (0,0), string is 5, textField.text = "" (The textField.text isn't changed yet, it depends on return value of delegate function, if true it'll replace the textField.text with in range with string) 3. input 7 -> range is (1,0), string is 7, textField.text = "5" 4. input backspace -> range is (2, 1), string is "", textField = "57"

After 4, your textField.text = "5"

so you can revise your code:

let stringAfterChanged = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
raDelegate?.durationChanged(hrs: stringAfterChanged)
nghiahoang
  • 395
  • 3
  • 9
0

You used shouldChangeCharactersIn wrongly. update your code with your controller extension

extension YourController: UITextFieldDelegate {
        func textField(_ textField: UITextField,
                       shouldChangeCharactersIn range: NSRange,
                       replacementString string: String) -> Bool {
            if let text = textField.text,
               let textRange = Range(range, in: text) {
               let updatedText = text.replacingCharacters(in: textRange,
                                                           with: string)

                raDelegate?.durationChanged(hrs: updatedText)
            }
            return true
        }
    }

Or try this workaround

extension YourController: UITextFieldDelegate {

            func textField(_ textField: UITextField,
                           shouldChangeCharactersIn range: NSRange,
                           replacementString string: String) -> Bool {
     let previousText:NSString = textField.text! as NSString
     let updatedText = previousText.replacingCharacters(in: range, with: string)
     raDelegate?.durationChanged(hrs: updatedText)

      return true
}
Jawad Ali
  • 11,075
  • 2
  • 25
  • 39