简体   繁体   中英

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

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)
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM