我正在尝试在我的SwiftUI应用中实现一些UIKit组件。我已成功将UISlider添加到我的SwiftUI视图。但是有一件事困扰着我。当我移动滑块时,值可以更新,但是我很想知道为什么context.coordinator.value.wrappedValue保持不变?这是我的实现:
time
现在这让我很麻烦:
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)
}
}
}
这些值应该相同,或者至少我希望它们相同,但是却不相同?
答案 0 :(得分:1)
功劳应归功于@Asperi和@ClausJørgensen
如果您异步打印context.coordinator的包装值,如下所示,则它的值是正确的。
我不知道为什么会这样,我对此很好奇。从理论上讲,由于context.coordinator.value应该与UISliderView和Coordinator具有相同的绑定。因此,它们应该在同一时间更新。
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.23255814611911774