我有不同类型 View 的元组 some View
,也可以有一些 Group 也是泛型类型。现在我考虑如何解析这样的结构来实现 View 数组。
这是初始化程序和调试器屏幕截图
public init<A: View, B: View>(@ViewBuilder content: () -> TupleView<(A, B)>) {
let views = content().value
self.childs = [AnyView(views.0), AnyView(views.1)]
}
更新 1
我已经尝试实现@ViewBuilder 返回两个组的 TupleView 的初始化程序,然后我可以通过实现初始化程序的所有排列来启用 View 构建器中组的不同组合。
public init<A: View, B: View>(@ViewBuilder content: () -> TupleView<(Group<A>, Group<B>)>) {
let groups = content().value
groups.0.content...
groups.1.content... // here content is internal
}
但这里的问题是第一个 Group< TupleView < ... >
不提供对内容属性的公共(public)访问(它被标记为内部)
所以我无法访问此属性的内容。我什至尝试过 Mirror(reflecting: groups.0) 但它也没有帮助,因为我无法将其子值转换为适当的 TupleView ,因为我不知道?泛型类型。
更新 2
所以现在唯一的解决方法 为我的自定义容器添加 10 个以上的 View ,然后像我一样布局这些 View 以实现我自己的自定义 分组 查看而不是组!
struct Grouping: View {
let childs : [AnyView]
var body: some View {
EmptyView()
}
public init<A: View>(@ViewBuilder content: () -> A) {
// this init will be used for any non-supported number of TupleView
let view = content()
self.childs = [AnyView(view)]
}
// MARK: TupleView support
public init<A: View, B: View>(@ViewBuilder content: () -> TupleView<(A, B)>) {
let views = content().value
self.childs = [AnyView(views.0), AnyView(views.1)]
}
// ... other 10 init permutations returning TupleView of views
}
而在我的 自定义容器 View 然后我可以实现 初始化 采取这个分组 TupleView。
public init(@ViewBuilder content: () -> TupleView<(Grouping, Grouping)>) {
let groups = content().value
self.childs = groups.0.childs + groups.1.childs
}
它接缝完成了这项工作。我不明白为什么 Apple 不提供对群组内容及其 subview 的公开访问。这样我们制作自定义布局组件的方法非常有限
最佳答案
你可以试试这个:
func recursiveViewToViewList<V0: View>(viewGroup: V0) -> [AnyView] {
[AnyView(viewGroup)]
}
func recursiveViewToViewList<V0: View, V1: View>(viewGroup: TupleView<(V0,V1)>) -> [AnyView] {
[]
+ recursiveViewToViewList(viewGroup: viewGroup.value.0)
+ recursiveViewToViewList(viewGroup: viewGroup.value.1)
}
func recursiveViewToViewList<V0: View, V1: View, V2: View>(viewGroup: TupleView<(V0,V1,V2)>) -> [AnyView] {
[]
+ recursiveViewToViewList(viewGroup: viewGroup.value.0)
+ recursiveViewToViewList(viewGroup: viewGroup.value.1)
+ recursiveViewToViewList(viewGroup: viewGroup.value.2)
}
func recursiveViewToViewList<V0: View, V1: View, V2: View, V3: View>(viewGroup: TupleView<(V0,V1,V2,V3)>) -> [AnyView] {
[]
+ recursiveViewToViewList(viewGroup: viewGroup.value.0)
+ recursiveViewToViewList(viewGroup: viewGroup.value.1)
+ recursiveViewToViewList(viewGroup: viewGroup.value.2)
+ recursiveViewToViewList(viewGroup: viewGroup.value.3)
}
func recursiveViewToViewList<Data: Collection, ID: Hashable, Content: View>(viewGroup: ForEach<Data, ID, Content>) -> [AnyView] {
viewGroup.data.flatMap {
recursiveViewToViewList(viewGroup: viewGroup.content($0))
}
}
struct Grouping: View {
let childs: [AnyView]
public init<A: View>(@ViewBuilder content: () -> A) {
childs = recursiveViewToViewList(viewGroup: content())
}
}
编辑:这不起作用。重载解析是在泛型实现之前完成的,因此当您只有
: View
时,仅解析第一个函数(基本情况)对泛型参数的约束。最好的机会可能是在那里进行动态调度(可能使用反射,因为您无法对带有开放参数的泛型进行类型检查),尽管我不知道这是否可行,也不知道如何去做。
关于SwiftUI TupleView 和泛型,如何递归解析某些 View 和 Group 的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59047885/