在UIViewControllerRepresentable中的ViewController上设置属性

时间:2020-07-16 11:56:24

标签: swift swiftui

如何更改通过显示的UIViewController上的属性。 UIViewControllerRepresentable吗?

我将如何期望工作的示例代码,但是没有成功。我该如何运作?

(颜色只是一个例子,请不要专注于此)

class MyViewController: UIViewController {
    var color: UIColor? = nil {
        didSet {
            guard isViewLoaded else { return }
            view.layer.backgroundColor = color?.cgColor
        }
    }

    override func viewDidLoad() {
        view.layer.backgroundColor = color?.cgColor
    }
}

struct MyView: UIViewControllerRepresentable {
    @State private var color: UIColor?

    func makeUIViewController(context: UIViewControllerRepresentableContext<MyView>) -> MyViewController {
        let viewController = MyViewController()
        viewController.color = color // always nil?
        return viewController
    }


    func updateUIViewController(_ uiViewController: MyViewController,
                                context: UIViewControllerRepresentableContext<MyView>) {
        uiViewController.color = color // always nil?
    }
}

extension MyView {
    func color(_ color: UIColor) -> MyView {
        self.color = color // does nothing?
        return self
    }
}

struct ContentView: View {
    var body: some View {
        MyView()
            .color(.magenta)
    }
}

2 个答案:

答案 0 :(得分:1)

这里是可行的方法(如所见,如果您希望颜色可以在外部进行修改)。使用Xcode 11.4 / iOS 13.4进行了测试

struct MyView: UIViewControllerRepresentable {
    @Binding var color: UIColor?

    func makeUIViewController(context: UIViewControllerRepresentableContext<MyView>) -> MyViewController {
        let viewController = MyViewController()
        viewController.color = color // always nil?
        return viewController
    }


    func updateUIViewController(_ uiViewController: MyViewController,
                                context: UIViewControllerRepresentableContext<MyView>) {
        uiViewController.color = color // always nil?
    }
}

struct ContentView: View {
    @State private var color: UIColor? = .magenta

    var body: some View {
        MyView(color: $color)
//        MyView(color: .constant(.magenta)) // alternate usage
    }
}

答案 1 :(得分:0)

另一种基于Asperi回答的思想的解决方案:

struct MyView: UIViewControllerRepresentable {
    private class State: ObservableObject {
        var color: UIColor?
    }

    @Binding private var state: State

    init() {
        _state = .constant(State())
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<MyView>) -> MyViewController {
        return MyViewController()
    }

    func updateUIViewController(_ uiViewController: MyViewController,
                                context: UIViewControllerRepresentableContext<MyView>) {
        uiViewController.color = state.color
    }
}

extension MyView {
    func color(_ color: UIColor) -> MyView {
        self.state.color = color
        return self
    }
}

或更简单的版本,我们只对打包的ViewController直接使用@Binding

struct MyView: UIViewControllerRepresentable {
    @Binding private var viewController: MyViewController

    init() {
        _viewController = .constant(MyViewController())
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<MyView>) -> MyViewController {
        return viewController
    }

    func updateUIViewController(_ uiViewController: MyViewController,
                                context: UIViewControllerRepresentableContext<MyView>) {
    }
}

extension MyView {
    func color(_ color: UIColor) -> MyView {
        self.viewController.color = color
        return self
    }
}