Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

SwiftUI: Weird behaviour of Slider when it is in the leading/trailing of navigation bar items

Ask Question

I'm having trouble placing a Slider as a view in the trailing of navigation bar. Since it's hooked to a state, changing the state of it is very jumpy and not smooth at all.

Here's my sample code:

struct ContentView: View {
    @State var opacityValue: Double = 1
    var body: some View {
        NavigationView {
            GeometryReader { geometry in
                VStack {
                    Slider(value: self.$opacityValue, in: 0...100, step: 5) { changed in
                    Image(systemName: "photo.fill")
                        .foregroundColor(.blue)
                        .padding()
                        .opacity(opacityValue / 100)
                }.navigationBarItems(trailing: HStack(spacing: 20) {
                    Slider(value: self.$opacityValue, in: 0...100, step: 5) { _ in
                    }.frame(width: 100)
                }).frame(width: geometry.size.width / 2)

The slider that I have in the regular VStack changes the opacity very smooth (and it even moves the slider that is in the nav bar.) But on the other hand, moving the slider that is in the nav bar is very glitchy/jumpy.

Is there a way to make this work?

You can make new View model for Image with @Binding property and pass your opacity through it, which will stop glitching movement on slider when @State property changes and View have to be refreshed

struct ContentView: View {
    @State var opacityValue: Double = 1
    var body: some View {
        NavigationView {
            GeometryReader { geometry in
                VStack {
                    Slider(value: self.$opacityValue, in: 0...100, step: 5) { _ in
                    ImageOpacityView(opacity: $opacityValue)
                }.navigationBarItems(trailing: HStack(spacing: 20) {
                    Slider(value: self.$opacityValue, in: 0...100, step: 5) { _ in
                    }.frame(width: 100)
                }).frame(width: geometry.size.width / 2)
    struct ImageOpacityView: View {
        @Binding var opacity: Double
        var body: some View {
            Image(systemName: "photo.fill")
                .foregroundColor(.blue)
                .padding()
                .opacity(opacity / 100)
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.