Search code examples
swiftbindingstatewatchkitswiftui

How to fire a function on @State variable change from Apple Watch Digital Crown with SwiftUI?


The code below creates a ring in SwiftUI that is completed when the Digital Crown is rotated. I'd like to fire a function when the "crownValue" state variable reaches a value of 5.0, which is when the circle is fully visible.

How can I have a function that reacts to the crown value change in order to perform a web request?

Thanks

struct commandDetailView: View {

    @State var crownValue = 0.1


    var body: some View {
        VStack {
            Circle()
                .trim(from: 0.0, to: CGFloat(crownValue / 5.0))
                .stroke(Color.blue, style: StrokeStyle(lineWidth: 12, lineCap: CGLineCap.round, lineJoin: .round))
                .frame(width: 120, height: 120)

            Text("Spin to Start Car")


        }
    .focusable(true)
        .digitalCrownRotation($crownValue, from: 0.1, through: 5.0, sensitivity: .low, isContinuous: false, isHapticFeedbackEnabled: true)
        .onAppear() {

        }

    }
}

Solution

  • Unfortunately the easiest thing to do right now is use a custom binding that wraps your crownValue. (I say unfortunately, as I have an open ticket with Apple about the lack of didSet for @State and how to work around it, with no resolution yet.)

    
    var crownValueBinding: Binding<Double> {
      Binding<Double>(
        get: { self.crownValue },
        set: { newValue in
          self.crownValue = newValue
          self.myFunc() // Whatever you like
        }
      )
    }
    

    And to use it:

     SomeView()
       .digitalCrownRotation(self.crownValueBinding, ...) // NOTE: No $ sign!