1

so I am making UILabel live update from UiTextfield (user input). I am using the code from this thread Swift3: Live UiLabel update on user input

but somehow, my UILabel always left one character when I fully erase the text in my UITextField. like the .gif in here http://g.recordit.co/SPQWnYtHJg.gif

and it seems one character is always missing like the picture below

enter image description here

enter image description here

here is the code I use

import UIKit

class CreateEventVC: UIViewController {

    @IBOutlet weak var eventNameTextField: UITextField!
    @IBOutlet weak var eventNameLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        //initial value
        eventNameLabel.text = " "

        // delegate declaration
        eventNameTextField.delegate = self
    }

}


extension CreateEventVC : UITextFieldDelegate {

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        eventNameLabel.text = eventNameTextField.text
        return true
    }
}

I initially suspect because I add this line in viewDidload

eventNameLabel.text = " "

but if i delete this one, the problem is still there

what should I do ?

sarah
  • 3,819
  • 4
  • 38
  • 80
  • I might be wrong - but `shouldChangeCharactersIn` has not yet updated the text in the text field yet - this makes sense, as you can filter out content which does meet the needs of the implementation without directly manipulating the textfield itself. Instead, you will need to take the text currently in the text field and apply the changes yourself before updating the label – MadProgrammer Apr 14 '18 at 23:53
  • Maybe what you need is something more like `eventNameLabel.text = (textField.text as NSString).replacingCharacters(in: range, with: string)` – MadProgrammer Apr 14 '18 at 23:58

2 Answers2

1

textField:shouldChangeCharactersIn:range:replacementString is called before the change is applied to the text field, this allows your app to veto the request and filter out unwanted content.

The problem is, you're relying on the text field's text. Instead, you need build the resulting value from the information passed to the delegate and apply that

Maybe something more like...

extension CreateEventVC: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let text = textField.text ?? ""
        eventNameLabel.text = (text as NSString).replacingCharacters(in: range, with: string)
        return true;
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0
class CreateEventVC: UIViewController {

    @IBOutlet weak var eventNameTextField: UITextField!
    @IBOutlet weak var eventNameLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        //initial value
        eventNameLabel.text = " "

        eventNameTextField.addTarget(self, action: #selector(onTextFieldTextDidChange), for: .editingChanged)
    }


    @objc func onTextFieldTextDidChange() {

       eventNameLabel.text = eventNameTextField.text

    }

}

Explanations:

We add target to the eventNameTextField which will call the onTextFieldTextDidChange func each time the textField text is changed.

Dmitry
  • 2,963
  • 2
  • 21
  • 39