首页 > 解决方案 > UIViewControllerRepresentable 中包含的@Binding 未更新

问题描述

我有一个UIHostingController包含在 aUIViewControllerRepresentable中,它包含对绑定的引用。当绑定更改时,updateUIViewController会调用,但不会自动重新渲染底层视图。我如何向嵌入式 UIHostingController发出它需要更新其内容的信号?

以下是该场景的简化版本。请注意,当步进器更改时,第一个会Text自动更新,但包含在其中的文本PassthroughView UIViewControllerRepresentable不会自动看到其内容被重新渲染。

import SwiftUI

struct ContentView: View {
    @State var number = 99

    var body: some View {
        VStack {
            Stepper("Stepper", value: $number)
            Text("Direct Value: \(number)")
            PassthroughView {
                Text("Passthrough Value: \(number)")
            }
            Spacer()
        }.font(.headline)
    }
}

struct PassthroughView<V: View> : UIViewControllerRepresentable {
    typealias UIViewControllerType = UIHostingController<V>
    let content: V

    init(@ViewBuilder _ content: () -> V) {
        self.content = content()
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<PassthroughView<V>>) -> UIViewControllerType {
        UIViewControllerType(rootView: content)
    }

    func updateUIViewController(_ controller: UIViewControllerType, context: UIViewControllerRepresentableContext<PassthroughView<V>>) {
        // this is called when the binding changes;
        // how to tell the UIHostingController to re-render?
    }
}

标签: swiftui

解决方案


以下代码将按需要工作:

我不确定这是否是一种好习惯,因为我对 UIKit 不是很熟悉。

struct PassthroughView<V: View> : UIViewControllerRepresentable {
    typealias UIViewControllerType = UIHostingController<V>
    let content: V

    init(@ViewBuilder _ content: () -> V) {
        self.content = content()
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<PassthroughView<V>>) -> UIViewControllerType {
        UIViewControllerType(rootView: content)
    }

    func updateUIViewController(_ controller: UIViewControllerType, context: UIViewControllerRepresentableContext<PassthroughView<V>>) {
        // this is called when the binding changes;
        // how to tell the UIHostingController to re-render?
        controller.rootView = content
    }
}

struct ContentView: View {

    @State var number = 99

    var body: some View {
        VStack {
            Stepper("Stepper", value: $number)
            Text("Direct Value: \(number)")
            PassthroughView {
                Text("Passthrough Value: \(number)")
            }
            Spacer()
        }.font(.headline)
    }

}

我希望这有帮助!


推荐阅读