首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI为什么context.coordinator.value.wrappedValue只返回初始值?

SwiftUI为什么context.coordinator.value.wrappedValue只返回初始值?
EN

Stack Overflow用户
提问于 2020-10-12 22:01:30
回答 1查看 154关注 0票数 0

我正在尝试在我的SwiftUI应用程序中实现一些UIKit组件。我已经成功地将UISlider添加到我的SwiftUI视图中。但有一件事困扰着我。当我移动滑块时,值是更新的,但我很好奇为什么context.coordinator.value.wrappedValue保持不变?下面是我的实现:

代码语言:javascript
复制
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)
    }
}
}

这就是让我困扰的部分:

代码语言:javascript
复制
print("Value: \(value)")
print("Wrapped value: \(context.coordinator.value.wrappedValue)")

这些值应该是相同的,或者至少我希望它们是相同的,但事实并非如此?

EN

回答 1

Stack Overflow用户

发布于 2020-10-21 16:38:29

这个功劳应该归功于@Asperi和@Claus Jørgensen

如果异步打印context.coordinator的包装值,如下所示,它的值是正确的。

我不知道为什么会发生这种情况,我对此太好奇了。从理论上讲,由于context.coordinator.value应该是UISliderView和协调器的相同绑定。因此,它们应该完全相同的时间更新。

代码语言:javascript
复制
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)
        }
    }
}
代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64319400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档