如何使 UIViewRepresentable @ViewBuilder 处理动态内容? [英] How to make a UIViewRepresentable @ViewBuilder work with dynamic content?
问题描述
是否可以制作一个 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()
被调用时,我的动态数据是空的,后来被填充或更新.我在初始化时评估了我的 UIViewRepresentable
的 content
,并且不在 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屋!