I have an app where there are 2 views, one with a UILabel and another with a UITextField. I would like it so the moment you are done editing the Text Field, the label changes to the TF's value. The text field stores its value in a UserDefaults and when my Label's View loads, it shows the value of the UD key on the label. Again, I would like it so the moment you are done editing the Text Field, the label changes to the TF's value.
Below is my Label's View's Controller
My TextField's View's Controller
Below is my Label's View's Controller
Code Block Swift struct myStruct { static var money = 0.00 } import UIKit class ViewController: UIViewController { @IBOutlet weak var moneyLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() let ud = UserDefaults.standard myStruct.money = ud.double(forKey: "Money") moneyLabel.text = String(ud.double(forKey: "Money")) } }
My TextField's View's Controller
Code Block swift import UIKit class AddMoneyViewController: UIViewController { let userDefaults = UserDefaults.standard @IBOutlet weak var TextField: UITextField! override func viewDidLoad() { super.viewDidLoad() } @IBAction func TFEditingDidEnd(_ sender: Any) { userDefaults.set(TextField.text, forKey: "Money") let moneyAtPoint1 = userDefaults.double(forKey: "Money") print(moneyAtPoint1) } }
UserDefaults is a KVO compliant class and you can observe on its member "Money" as follows.
If you want to watch on Double value, you need to set a value of Double, not String.
(This is not a critical issue about your app's behavior, but you should better use Capitalized id only for types in Swift. TextField or TFEditingDidEnd is not appropriate for property name or method name.)
One more, you should better consider using NumberFormatter to convert Double and the text of the text field.
Code Block extension UserDefaults { //Dummy definition to make KeyPath available @NSManaged var Money: Double } class ViewController: UIViewController { @IBOutlet weak var moneyLabel: UILabel! var udObservation: NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() let ud = UserDefaults.standard moneyLabel.text = String(ud.double(forKey: "Money")) udObservation = ud.observe(\.Money, options: .new) {ud, change in if let newValue = change.newValue { self.moneyLabel.text = String(newValue) } } } }
If you want to watch on Double value, you need to set a value of Double, not String.
Code Block import UIKit class AddMoneyViewController: UIViewController { let userDefaults = UserDefaults.standard @IBOutlet weak var TextField: UITextField! override func viewDidLoad() { super.viewDidLoad() } @IBAction func TFEditingDidEnd(_ sender: Any) { //You need to set `Double` value, not `String` userDefaults.set(Double(TextField.text ?? "") ?? 0, forKey: "Money") let moneyAtPoint1 = userDefaults.double(forKey: "Money") print(moneyAtPoint1) } }
(This is not a critical issue about your app's behavior, but you should better use Capitalized id only for types in Swift. TextField or TFEditingDidEnd is not appropriate for property name or method name.)
One more, you should better consider using NumberFormatter to convert Double and the text of the text field.