Edd*_*ddy 6 custom-view swiftui viewbuilder
所以我试图创建一个视图,它接受 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)
}
}
Run Code Online (Sandbox Code Playgroud)
所以在我写“here”的地方,如果有意义的话,我想遍历内容的视图。我将编写一个不起作用的代码,但它解释了我想要实现的目标:
ForEach(content.subviews) { view in
view
Divider()
}
Run Code Online (Sandbox Code Playgroud)
怎么做?
我刚刚回答了另一个类似的问题,链接在这里。对此的任何改进都将针对链接的答案进行,因此请先检查那里。
GitHub 链接(但更高级)位于 Swift 包中
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!
}
}
}
Run Code Online (Sandbox Code Playgroud)
你的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, id: \.self) { index in
if index != 0 {
Divider()
}
content[index]
}
}
// .background(Color.black)
.cornerRadius(14)
}
}
Run Code Online (Sandbox Code Playgroud)
最后是主要的事情,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)
}
}
Run Code Online (Sandbox Code Playgroud)
结果:
所以我最终这样做了
\n@_functionBuilder\nstruct UIViewFunctionBuilder {\n static func buildBlock<V: View>(_ view: V) -> some View {\n return view\n }\n static func buildBlock<A: View, B: View>(\n _ viewA: A,\n _ viewB: B\n ) -> some View {\n return TupleView((viewA, Divider(), viewB))\n}\n}\nRun Code Online (Sandbox Code Playgroud)\n然后我像这样使用我的函数生成器
\nstruct BoxWithDividerView<Content: View>: View {\n let content: () -> Content\n init(@UIViewFunctionBuilder content: @escaping () -> Content) {\n self.content = content\n }\n var body: some View {\n VStack(spacing: 0.0) {\n content()\n }\n .background(Color(UIColor.AdUp.carbonGrey))\n .cornerRadius(14)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但问题是这只适用于最多 2 个表达式视图。I\xe2\x80\x99m 将发布一个单独的问题,了解如何向其传递数组
\n| 归档时间: |
|
| 查看次数: |
778 次 |
| 最近记录: |