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 与动态内容一起使用?
基础教程推荐
- iOS4 创建后台定时器 2022-01-01
- libGDX 从精灵或纹理中获取像素颜色 2022-01-01
- 如何从 logcat 中删除旧数据? 2022-01-01
- 通过重定向链接在 Google Play 中打开应用 2022-01-01
- Cocos2d iPhone 非矩形精灵触摸检测 2022-01-01
- AdMob 广告未在模拟器中显示 2022-01-01
- navigator.geolocation.getCurrentPosition 在 Android 浏览器上 2022-01-01
- iPhone - 获取给定地点/时区的当前日期和时间并将其与同一地点的另一个日期/时间进行比较的正确方法 2022-01-01
- NSString intValue 不能用于检索电话号码 2022-01-01
- Android:getLastKnownLocation(LocationManager.NETWORK_PROVIDER 2022-01-01
