UIViewRepresentable 未更新与 ObservedObject 属性的绑定?

Tig*_*old 5 swift swiftui uiviewrepresentable swiftui-14.2-defect

此视图是一个适应我的 SwiftUI 项目的 UIKit 滑块,因为在 SwiftUI 中Slider无法更改其轨道颜色,这可能是一个错误,因为您应该能够使用.accentColor.

不管怎样,这个滑块根据它的值改变它的轨道颜色,从绿色到红色。value如果绑定到普通属性,整个事情就完美地工作了(尽管我的渐变还不是很好)@State,但是当你尝试将它附加到它的属性时,@ObservedObject它就会中断,尽管轨道颜色仍然有效,但它永远不会改变基础价值。我想这只是一个错误,但更可能的是这里有一些东西需要修复。

struct RedscaleSlider: UIViewRepresentable {
    
    @Binding var value: Double
    
    var min: Double
    var max: Double
    
    class Coordinator: NSObject {
        @Binding var value: Double
        var min: Double
        var max: Double
        
        init(value: Binding<Double>, min: Double = 0, max: Double = 100) {
           _value = value
            self.min = min
            self.max = max
        }
        
        @objc func valueChanged(_ sender: UISlider) {
            self.value = Double(sender.value)
            sender.minimumTrackTintColor = green_to_red_gradient(value: (Double(sender.value) - min) / (max - min)).into_UIKit_color()
        }
    }
    
    var thumb_color: UIColor = .white
    var track_color: UIColor = .systemBlue
    
    func makeUIView(context: Context) -> UISlider {
        let slider = UISlider(frame: .zero)
        
        slider.addTarget(
            context.coordinator,
            action: #selector(Coordinator.valueChanged),
            for: .valueChanged
        )
        
        slider.thumbTintColor = thumb_color
        slider.minimumTrackTintColor = track_color
        slider.minimumValue = Float(min)
        slider.maximumValue = Float(max)
        slider.value = Float(value)
        
        return slider
    }
    
    func updateUIView(_ UI_View: UISlider, context: Context) {
        UI_View.value = Float(self.value)
    }
    
    func makeCoordinator() -> RedscaleSlider.Coordinator {
        Coordinator(value: $value, min: self.min, max: self.max)
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:如何使用它的示例:

class ViewModel: ObservableObject {
    @Published var danger_level: Double
}
struct ExampleView: View {
    @ObservedObject var view_model = ViewModel(danger_level: 50)
    
    var body: some View {
        VStack {
            Text(view_model.danger_level.description)
            RedscaleSlider(value: $view_model.danger_level)
            // should update view model just like a Stepper would
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

dav*_*dev 0

accentColor这样对我来说工作得很好..

另外,您的代码可以与 ObservableObject 一起正常工作。这是演示代码:

class ViewModel : ObservableObject {
    @Published var double : Double = 0.0
}
struct ContentView : View {
    @State private var value: Double = 0
    
    @ObservedObject var viewModel = ViewModel()

    var body : some View {
        Slider(value: $value, in: -100...100, step: 0.1)
            .accentColor(.red) //<< here accent color
        
        RedscaleSlider(value: $viewModel.double, min: 5.0, max: 250.0)
        Text(String(viewModel.double))
    }
    
}
Run Code Online (Sandbox Code Playgroud)