UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

ObservableObject => TextField => Doubles

Forums > SwiftUI

I have an Observable Object that is tracking several doubles. They are linked to TextFields in my ContentView.

I discovered that I could link them using value: and formatter: instead of text:

TextField( "Double Value", value: $OO.myFirstDouble, formatter: NumberFormatter.decimal )

extension NumberFormatter {
    static var decimal: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.minimumFractionDigits = 3
        formatter.numberStyle = .decimal
        return formatter
    }
}

The problem is that when you enter anything into the fields, the data does not propagate to the observable object Unless you click "return" on the keyboard. To make matters more exciting, decimalPad and numberPad don't have an enter key by default (I haven't gotten to that part yet).

If you use text:

TextField( "Double Value", text: $OO.myFirstDouble )

Then the data propagates with every entry or removal of a number

Running around in circles (because I was not smart enough to start git) I played with some things.

Have my Observable Object accept the strings for data, then create parallel calculated variables that convert the string to double when needed.

struct ContentView: View {
    @ObservedObject var tvm = OO()

    var body: some View {
            TextField("Present", text:  $OO.myFirstDouble )
     }
}

class OO: ObservableObject {
  @Published var myFirstDouble: String = "0"
  var firstDouble: Double {
      get {
          if let tmp: Double = Double(myFirstDouble) {
            return tmp
          }
          return 0
      }

      set(newValue) {
         myFirstDouble = String(format: "%0.4f", firstDouble)
      }
  }
}

That seems like an ugly solution.. But someone somewhere said we have ways of making this a little more compact...

So I tried building a class

class myStingyDouble {
    var value: Double
    var string: String {
        didSet {
            if let tmp: Double = Double(string) {
                value = tmp
            }
        }
    }
    var format: String
    var name: String

    init(name: String, value: Double, format: String) {
        self.string = String(format: format, value)
        self.value = value
        self.name = name
        self.format = format
    }

    func set(value: Double) {
        self.value = value
        self.string = String(format: self.format, value)
    }
}

but then that text field in the content view looked like

TextField( "Double Value", text: $OO.firstDouble.string )

This actually updated the OO without any problem. But when I used the values to calculate something and updated the OO within itself updating the myStringyDouble object, the data did not send back to the TextView...

Right now I have the cludgy version working. I have found references that suggest that multiple class levels are not supported yet in the Observable Object version.

The simple answer would be for the value:formatter version to work (and I think it is the "right" path). It is the wrong path because the user shouldn't have to figure out how to make a "return" happen.

(First post, apologies if I violated any rules...)

2      

Google sent me down a variety of other paths...

    let myDouble = Binding<String>(get:{ OO.myFirstDouble.string}, set:{OO.myFirstDouble.string = $0} ) 

This also worked in one direction.

I tried to use the objectWillUpdate->send() concept, but that didn't seem to trigger.

2      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.