How can I detect, when the user moves the slider if the value is incrementing or decrementing?

Hello, I have a question:

Given this Slider

import SwiftUI

struct VolumeControl: View {
        
    @State private var value: Float = -30.0

    var body: some View {
 
        HStack {
            Slider(value: $value, in: -48.0...0, step: 0.25)
            Text("\(value, specifier: "%.2f") dB")
                .font(.custom("", size: 18))
            }
            .onChange(of: value) { newValue in
                
                // how can i detect if the slider is incrementing or decrementing?
                  
            }
        }
    }
}

My question :thinking:

How can I detect, when the user moves the slider if the value is incrementing or decrementing?

If the user moves up the slider I need to call a method (for instance: volume up)

If the user moves down the slider I need to call another method (for instance: volume down)

1 Like
struct ContentView: View {
    @State private var value: Float = -30
    @State private var direction: ComparisonResult = .orderedSame

    var body: some View {
        VStack {
            Slider(
                value: Binding(
                    get: { value },
                    set: {
                        direction =
                            $0 < value ? .orderedDescending
                            : $0 > value ? .orderedAscending
                            : .orderedSame
                        value = $0
                    }
                ),
                in: -48.0 ... 0.0,
                step: 0.25
            )

            Text(
                direction == .orderedDescending ? "decreasing"
                : direction == .orderedAscending ? "increasing"
                : "not really creasing at all"
            )
        }
        .padding()
    }
}
3 Likes

WOW! Thanks a lot!

I didn't know ComparisonResult

1 Like

The documentation for onChange(of:) explains how you can compare the old and the new values (incl. a code sample):

The new value is passed into the closure. The previous value may be captured by the closure to compare it to the new value.

This would be something like this in your case:

Slider(value: $value, …)
…
    .onChange(of: value) { [oldValue = value] newValue in
        if newValue > oldValue {
            // volume up
        } else if newValue < oldValue {
            // volume down
        }
    }
3 Likes

:clap: :clap: :clap:
Thanks @ole !

1 Like