我正在尝试在我的SwiftUI应用程序中实现一些UIKit组件。我已经成功地将UISlider添加到我的SwiftUI视图中。但有一件事困扰着我。当我移动滑块时,值是更新的,但我很好奇为什么context.coordinator.value.wrappedValue保持不变?下面是我的实现:
import SwiftUI
struct UISliderView: UIViewRepresentable {
typealias UIViewType = UISlider
@Binding var value: Double
var minValue: Double
var maxValue: Double
func makeUIView(context: Context) -> UISlider {
let slider = UISlider(frame: .zero)
slider.maximumValue = Float(minValue)
slider.maximumValue = Float(maxValue)
slider.value = Float(value)
slider.addTarget(context.coordinator,
action: #selector(Coordinator.valueChanged(_:)),
for: .valueChanged)
return slider
}
func updateUIView(_ uiView: UISlider, context: Context) {
print("Value: \(value)")
print("Wrapped value: \(context.coordinator.value.wrappedValue)")
uiView.value = Float(value)
}
func makeCoordinator() -> Coordinator {
let coordinator = Coordinator(value: $value)
coordinator.id = 5
return coordinator
}
class Coordinator: NSObject {
var value: Binding<Double>
var id: Int = 0
init(value: Binding<Double>) {
self.value = value
}
@objc func valueChanged(_ sender: UISlider) {
value.wrappedValue = Double(sender.value)
}
}
}这就是让我困扰的部分:
print("Value: \(value)")
print("Wrapped value: \(context.coordinator.value.wrappedValue)")这些值应该是相同的,或者至少我希望它们是相同的,但事实并非如此?
发布于 2020-10-21 16:38:29
这个功劳应该归功于@Asperi和@Claus Jørgensen
如果异步打印context.coordinator的包装值,如下所示,它的值是正确的。
我不知道为什么会发生这种情况,我对此太好奇了。从理论上讲,由于context.coordinator.value应该是UISliderView和协调器的相同绑定。因此,它们应该完全相同的时间更新。
import SwiftUI
struct ContentView: View {
@State var value: Double = 0
var body: some View {
UISliderView(value: $value, minValue: 0, maxValue: 10)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct UISliderView: UIViewRepresentable {
typealias UIViewType = UISlider
@Binding var value: Double
var minValue: Double
var maxValue: Double
init(value: Binding<Double>, minValue: Double, maxValue: Double) {
print("UISliderView", #function)
self._value = value
self.minValue = minValue
self.maxValue = maxValue
}
func makeUIView(context: Context) -> UISlider {
print("UISliderView", #function)
let slider = UISlider(frame: .zero)
slider.maximumValue = Float(minValue)
slider.maximumValue = Float(maxValue)
// slider.value = Float(value)
slider.addTarget(context.coordinator,
action: #selector(Coordinator.valueChanged(_:)),
for: .valueChanged)
return slider
}
func updateUIView(_ uiView: UISlider, context: Context) {
print("UISliderView", #function, "coordinator", ObjectIdentifier(context.coordinator))
print("UISliderView", "Value: \(value)")
DispatchQueue.main.async {
print("UISliderView", "Wrapped value: \(context.coordinator.value.wrappedValue)")
}
uiView.value = Float(value)
}
func makeCoordinator() -> Coordinator {
print("UISliderView", #function)
let coordinator = Coordinator(value: $value)
coordinator.id = 5
return coordinator
}
class Coordinator: NSObject {
var value: Binding<Double>
var id: Int = 0
init(value: Binding<Double>) {
self.value = value
super.init()
print("Coordinator", #function, ObjectIdentifier(self))
}
@objc func valueChanged(_ sender: UISlider) {
print("Coordinator", #function, "newValue:", value.wrappedValue)
value.wrappedValue = Double(sender.value)
}
}
}UISliderView init(value:minValue:maxValue:)
UISliderView makeCoordinator()
Coordinator init(value:) ObjectIdentifier(0x00006000018b4d50)
UISliderView makeUIView(context:)
UISliderView updateUIView(_:context:) coordinator ObjectIdentifier(0x00006000018b4d50)
UISliderView Value: 0.0
UISliderView Wrapped value: 0.0
UISliderView updateUIView(_:context:) coordinator ObjectIdentifier(0x00006000018b4d50)
UISliderView Value: 0.0
UISliderView Wrapped value: 0.0
Coordinator valueChanged(_:) newValue: 0.0
Coordinator valueChanged(_:) newValue: 0.0
Coordinator valueChanged(_:) newValue: 0.0
UISliderView updateUIView(_:context:) coordinator ObjectIdentifier(0x00006000018b4d50)
UISliderView Value: 0.03875968977808952
UISliderView Wrapped value: 0.03875968977808952
Coordinator valueChanged(_:) newValue: 0.03875968977808952
UISliderView updateUIView(_:context:) coordinator ObjectIdentifier(0x00006000018b4d50)
UISliderView Value: 0.1550387591123581
UISliderView Wrapped value: 0.1550387591123581
Coordinator valueChanged(_:) newValue: 0.1550387591123581
UISliderView updateUIView(_:context:) coordinator ObjectIdentifier(0x00006000018b4d50)
UISliderView Value: 0.23255814611911774
UISliderView Wrapped value: 0.23255814611911774
Coordinator valueChanged(_:) newValue: 0.23255814611911774https://stackoverflow.com/questions/64319400
复制相似问题