theDC
theDC

Reputation: 6484

Swift: How to change textField text automatically when other textField got filled?

I implement custom cell that has two UITextFields. Anytime I fill one of the text field I want the other to react in being filled with converted value.

Tried didSet method but it does not seem to the solution

Example:

import UIKit

class ConverterTableViewCell: UITableViewCell, UITextFieldDelegate {

@IBOutlet weak var mgdlTextField: UITextField! {
    didSet
    {
        if let value = Double(mgdlTextField.text!){
            let newValue:Double = value / 38.6
            self.mmolTextField.text = "\(newValue)"
        }

    }
}

@IBOutlet weak var label: UILabel!
@IBOutlet weak var mmolTextField: UITextField!
override func awakeFromNib() {
    super.awakeFromNib()
    self.mgdlTextField.delegate = self

    self.mmolTextField.delegate = self

}

EDIT: I tried the code in the answer below and end up with this error:

enter image description here

Upvotes: 1

Views: 3845

Answers (1)

Cyril
Cyril

Reputation: 1649

The didSet is not the solution since it will react when you are assigning the mgdlTextField variable with a new UITextField instance.

Instead, you must register your view controller as the delegate of your textfield and implement the following UITextFieldDelegate method:

func textField(_ textField: UITextField,
shouldChangeCharactersInRange range: NSRange,
            replacementString string: String) -> Bool

In this method, just retrieve the value of your textfield and apply the logic your tried before.

import UIKit

class ConverterTableViewCell: UITextFieldDelegate {

    @IBOutlet weak var mgdlTextField: UITextField!
    @IBOutlet weak var mmolTextField: UITextField!

    override func awakeFromNib() {
        super.awakeFromNib()

        self.mgdlTextField.delegate = self
        self.mmolTextField.delegate = self
    }

    // MARK: UITextFieldDelegate methods

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

        dispatch_async(dispatch_get_main_queue()) { () -> Void in

            if textField == self.mgdlTextField {

                if let text = textField.text {
                    if let value = Double(text) {
                        self.mmolTextField.text = "\(value / 38.6)"
                        return
                    }
                }
                self.mmolTextField.text = ""


            } else {

                if let text = textField.text {
                    if let value = Double(text) {
                        self.mgdlTextField.text = "\(value * 38.6)"
                        return
                    }
                }
                self.mgdlTextField.text = ""
            }

        }

        return true
    }
}

The dispatch async is here to ensure your value is updated before you actually do the transform.

Hope that helps.

EDIT: added some implementation code

Upvotes: 4

Related Questions