Barry Michael Doyle
Barry Michael Doyle

Reputation: 10588

SwiftUI Digital Crown stepping through numbers not working

I'm bashing my face against a wall trying to figure out why I can't get the .digitalCrownRotation feature to work on a Text UI Component in SwiftUI for WatchOS.

Here's my code:

import SwiftUI

struct ButtonView: View {
    @State private var isFocused = false
    @State private var value: Int = 0

    var body: some View {
        Button(action: {
            print("clicked")
        }) {
            Text("\(value)")
            .contentShape(Rectangle())
            .focusable { self.isFocused = $0 }
            .digitalCrownRotation(self.$value, from: 0, through: 9, by: 1, sensitivity: .medium, isContinuous: true, isHapticFeedbackEnabled: true)
        }
        .background(self.isFocused ? Color.green : Color.white)
    }
}

Everything worked fine up until the pointer where I tried to add the .digitalCrownRotation functionality.

Whenever I try to build I'm faced with the following 2 build fail messages:

Argument type 'Int.Stride' (aka 'Int') does not conform to expected type 'BinaryFloatingPoint' Argument type 'Int' does not conform to expected type 'BinaryFloatingPoint'

I'm basically trying to use the digital crown to step through numbers (integers) from 0 to 9 when the buttons are focused. But it's not working and I'm not sure what to do to resolve it.

Upvotes: 2

Views: 1577

Answers (2)

Narsail
Narsail

Reputation: 797

I came across this post as I was facing a similar situation. I solved the jankyness of the integer value by rounding up/down/tonearest based of the velocity of the crown.

@State crownValue: Double
@State integerValue: Int

Text("(integerValue)")
  .focusable(true)
  .digitalCrownRotation(
       detent: $values.crownValue,
       from: 0,
       through: 100,
       by: 1,
       sensitivity: .low,
       isContinuous: false,
       isHapticFeedbackEnabled: true,
       onChange: { crownEvent in
           integerValue = round(value: crownEvent.offset, velocity: crownEvent.velocity)
       })

private func round(value: Double, velocity: CDouble) -> Double {
   let roundingRule: FloatingPointRoundingRule
   switch velocity {
       case let x where x < 0: roundingRule = .up
       case let x where x == 0: roundingRule = .toNearestOrAwayFromZero
       case let x where x > 0: roundingRule = .down
       default: roundingRule = .toNearestOrAwayFromZero
   }
   return value.rounded(roundingRule)
}

Upvotes: 1

Asperi
Asperi

Reputation: 257543

Here is declaration

    public func digitalCrownRotation<V>(_ binding: Binding<V>, from minValue: V, through 
                   maxValue: V, by stride: V.Stride? = nil, sensitivity: DigitalCrownRotationalSensitivity = .high, 
                   isContinuous: Bool = false, isHapticFeedbackEnabled: Bool = true) -> some View 
                   where V : BinaryFloatingPoint, V.Stride : BinaryFloatingPoint ```

so as seen and error reports V type (which is detected from your provided binding) should be floating point, but your value is Int, which is not floating point, so fix is simple

@State private var value: Double = 0

Upvotes: 2

Related Questions