因此,我试图创建一个包含viewBuilder内容的视图,循环浏览该内容的视图,并在每个视图与另一个视图之间添加分隔线。
struct BoxWithDividerView<Content: View>: View {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack(alignment: .center, spacing: 0) {
// here
}
.background(Color.black)
.cornerRadius(14)
}
}
所以,在我写“ here”的地方,我想遍历内容的视图,如果这是有道理的。我将编写无效的代码,但该代码说明了我要实现的目标:
ForEach(content.subviews) { view in
view
Divider()
}
该怎么做?
答案 0 :(得分:1)
所以我最终这样做了
@_functionBuilder
struct UIViewFunctionBuilder {
static func buildBlock<V: View>(_ view: V) -> some View {
return view
}
static func buildBlock<A: View, B: View>(
_ viewA: A,
_ viewB: B
) -> some View {
return TupleView((viewA, Divider(), viewB))
}
}
然后我像这样使用函数构建器
struct BoxWithDividerView<Content: View>: View {
let content: () -> Content
init(@UIViewFunctionBuilder content: @escaping () -> Content) {
self.content = content
}
var body: some View {
VStack(spacing: 0.0) {
content()
}
.background(Color(UIColor.AdUp.carbonGrey))
.cornerRadius(14)
}
}
但是问题是这仅适用于最多2个表达式视图。我将发布一个单独的问题,关于如何能够将其传递给数组
答案 1 :(得分:1)
我刚刚回答了另一个类似的问题,link here。将对链接的答案进行任何改进,因此请先检查那里。
然而,这里的答案具有相同的 TupleView
扩展名,但视图代码不同。
用法:
struct ContentView: View {
var body: some View {
BoxWithDividerView {
Text("Something 1")
Text("Something 2")
Text("Something 3")
Image(systemName: "circle") // Different view types work!
}
}
}
您的BoxWithDividerView
:
struct BoxWithDividerView: View {
let content: [AnyView]
init<Views>(@ViewBuilder content: @escaping () -> TupleView<Views>) {
self.content = content().getViews
}
var body: some View {
VStack(alignment: .center, spacing: 0) {
ForEach(content.indices) { index in
if index != 0 {
Divider()
}
content[index]
}
}
// .background(Color.black)
.cornerRadius(14)
}
}
最后是最重要的,TupleView
扩展名:
extension TupleView {
var getViews: [AnyView] {
makeArray(from: value)
}
private struct GenericView {
let body: Any
var anyView: AnyView? {
AnyView(_fromValue: body)
}
}
private func makeArray<Tuple>(from tuple: Tuple) -> [AnyView] {
func convert(child: Mirror.Child) -> AnyView? {
withUnsafeBytes(of: child.value) { ptr -> AnyView? in
let binded = ptr.bindMemory(to: GenericView.self)
return binded.first?.anyView
}
}
let tupleMirror = Mirror(reflecting: tuple)
return tupleMirror.children.compactMap(convert)
}
}
结果: