-
-
Save prachigauriar/c508799bad359c3aa271ccc0865de231 to your computer and use it in GitHub Desktop.
| extension Binding where Value == Double { | |
| /// Returns a new version of the binding that scales the value logarithmically using the specified base. That is, | |
| /// when getting the value, `log_b(value)` is returned; when setting it, the new value is `pow(base, newValue)`. | |
| /// | |
| /// - Parameter base: The base to use. | |
| func logarithmic(base: Double = 10) -> Binding<Double> { | |
| Binding( | |
| get: { | |
| log10(self.wrappedValue) / log10(base) | |
| }, | |
| set: { (newValue) in | |
| self.wrappedValue = pow(base, newValue) | |
| } | |
| ) | |
| } | |
| } | |
| extension Slider where Label == EmptyView, ValueLabel == EmptyView { | |
| /// Creates a new `Slider` with a base-10 logarithmic scale. | |
| /// | |
| /// ## Example | |
| /// | |
| /// @State private var frequency = 1.0 | |
| /// | |
| /// var body: some View { | |
| /// Slider.withLog10Scale(value: $frequency, in: 1 ... 100) | |
| /// } | |
| /// | |
| /// - Parameters: | |
| /// - value: A binding to the unscaled value. | |
| /// - range: The unscaled range of values. | |
| /// - onEditingChanged: Documentation forthcoming. | |
| static func withLog10Scale( | |
| value: Binding<Double>, | |
| in range: ClosedRange<Double>, | |
| onEditingChanged: @escaping (Bool) -> Void = { _ in } | |
| ) -> Slider { | |
| return self.init( | |
| value: value.logarithmic(), | |
| in: log10(range.lowerBound) ... log10(range.upperBound), | |
| onEditingChanged: onEditingChanged | |
| ) | |
| } | |
| } |
2021 Apri update
…
Thank you! I’ve updated the gist to incorporate these changes. Glad it was of use to you!
When I tried using this on macOS, I encountered some glitches with the Slider. As far as I can tell, the issue is because certain values along the slider don't map back to the same floating-point value when run through log and pow().
Visually, the slider hitches back to a previous value and makes the slider no longer smooth. I tried to round the value before passing it to the slider, but that also causes issues with a mismatch between the two "sources of truth."
Best idea I could think of is making the log() representation the source of truth, as the zoomable scroll view can be more forgiving.
When I tried using this on macOS, I encountered some glitches with the Slider. As far as I can tell, the issue is because certain values along the slider don't map back to the same floating-point value when run through
logandpow().Visually, the slider hitches back to a previous value and makes the slider no longer smooth. I tried to round the value before passing it to the slider, but that also causes issues with a mismatch between the two "sources of truth."
Best idea I could think of is making the log() representation the source of truth, as the zoomable scroll view can be more forgiving.
@darknoon Can you post some sample code? I don’t see the glitches you’re describing. What range are you using?
Thanks for this, btw. I'm working on one I can use for different kinds of mappings and this got me started. It's still in progress.
https://gist.github.com/carlynorama/ad0a7449367b9a08e8c8525d5dcc2f8a
2021 Apri update