如何使 UIViewRepresentable @ViewBuilder 处理动态内容? [英] How to make a UIViewRepresentable @ViewBuilder work with dynamic content?

查看:44
本文介绍了如何使 UIViewRepresentable @ViewBuilder 处理动态内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以制作一个 UIViewRepresentable 视图,该视图采用 ViewBuilder 参数与动态内容(例如 ForEach 循环)一起工作?

Is it possible to make a UIViewRepresentable view which takes a ViewBuilder argument work with dynamic content such as ForEach loops?

我有以下 UIViewRepresentable 视图,我用它下拉到 UIKit 并获得一些自定义的 UIScrollView 行为:

I have the following UIViewRepresentable view which I’m using to drop down to UIKit and get some custom UIScrollView behaviour:

struct CustomScrollView<Content:View>: UIViewRepresentable {

    private let content: UIView
    private let scrollView = CustomUIScrollView()

    init(@ViewBuilder content: () -> Content) {
        self.content = UIHostingController(rootView: content()).view
        self.content.backgroundColor = .clear
    }

    func makeUIView(context: Context) -> UIView {
        scrollView.addSubview(content)
        // ...
        return scrollView
    }

    func updateUIView(_ uiView: UIView, context: Context) {}

}

这适用于静态内容,如下所示:

This works fine with static content as follows:

var body: some View {
    CustomScrollView {
        VStack {
            ForEach(1..<50) { number in
                Text(String(number))
            }
        }
    }
}

但动态内容失败,显示空白视图:

But it fails with dynamic content, showing a blank view:

var body: some View {
    CustomScrollView {
        VStack {
            ForEach(self.numbers) { number in
                Text(String(number))
            }
        }
    }
}

我明白这是因为当makeUIView()被调用时,我的动态数据是空的,后来被填充或更新.我在初始化时评估了我的 UIViewRepresentablecontent,并且不在 updateUIView() 中更新它.

I understand that this is because when makeUIView() is called my dynamic data is empty, and it is later filled or updated. I evaluate my UIViewRepresentable’s content at init, and don’t update it in updateUIView().

您如何在 updateUIView() 中更新动态子内容?我尝试将 @ViewBuilder 参数捕获为 @escaping 闭包,并在每次调用 updateUIView() 时对其进行评估,这似乎是正确的解决方案(尽管效率低下?),但到目前为止还没有运气.

How do you go about updating dynamic child content in updateUIView()? I tried capturing the @ViewBuilder parameter as an @escaping closure and evaluating it every time updateUIView() is called, which seems like the right solution (albeit inefficient?), but no luck so far.

推荐答案

@ViewBuilder 的评估失败,因为您在这里修改了错误的结构副本

Evaluation of @ViewBuilder fails because you mutating the wrong copy of the struct here

func updateUIView(_ uiView: UIView, context: Context) {}

你应该直接用 content()

更新答案:删除了带有协调器的解决方案,因为在某些情况下它不会按预期工作

Updated Answer: Removed solution with a coordinator, because in some cases it works not as expected

这篇关于如何使 UIViewRepresentable @ViewBuilder 处理动态内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆