How to make a UIViewRepresentable @ViewBuilder work with dynamic content?(如何使 UIViewRepresentable @ViewBuilder 与动态内容一起使用?)
问题描述
是否可以使带有 ViewBuilder
参数的 UIViewRepresentable
视图与动态内容(例如 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 与动态内容一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使 UIViewRepresentable @ViewBuilder 与动态内容一起使用?


- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01