swift - UIViewRepresentable 不更新绑定到 ObservedObject 属性?
问题描述
此视图是适用于我的 SwiftUI 项目的 UIKit 滑块,因为在 SwiftUISlider
中无法更改其轨道颜色,这可能是一个错误,因为您应该能够使用.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)
}
}
编辑:它应该如何使用的例子:
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
}
}
}
解决方案
@Binding
应该只用在View
/UIViewRepresentable
而不是@Binding
在Coordinator
开关中有一个init
接收init(_ parent: RedscaleSlider)
然后使用parent.value = Double(sender.value)
import SwiftUI
class RedscaleSliderViewModel : ObservableObject {
@Published var value : Double = 5
@Published var danger_level: Double = 7.5
}
struct ParentRedscaleSlider: View{
//@State var value: Double = 5
@StateObject var vm = RedscaleSliderViewModel()
var body: some View {
VStack{
Text(vm.danger_level.description)
RedscaleSlider(value: $vm.danger_level, min: 0, max: 10)
}
}
}
struct RedscaleSlider: UIViewRepresentable {
//@EnvironmentObject var vm: RedscaleSliderViewModel
@Binding var value: Double
var min: Double
var max: Double
class Coordinator: NSObject {
var parent: RedscaleSlider
init(_ parent: RedscaleSlider) {
self.parent = parent
}
@objc func valueChanged(_ sender: UISlider) {
let senderVal = Double(sender.value)
self.parent.value = senderVal
//Missing code
//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(self)
}
}
struct RedScaleSlider_Previews: PreviewProvider {
static var previews: some View {
ParentRedscaleSlider()
}
}
推荐阅读
- c++ - 如何在数组中找到字符串的长度?
- java - 为什么这两种比较 Class 对象的方法会产生不同的结果?
- javascript - 如何更改 html 日历表中的课程等课程
- jasper-reports - Jasperreports:如何将主数据集参数传递给多轴图表的子数据集?
- docker - Docker、nginx、nginx 代理未重定向到正确的容器
- import - 如何将二进制文件导入 DolphinDB?
- containers - 如何知道一个容器的内容?
- c# - 根据 DDD,我需要额外的存储库和模型吗
- java - eclipse中是否有启动(最喜欢的)外部应用程序的快捷键,例如参数化的maven构建?
- php - PHP中的嵌套循环可能吗?