gpt4 book ai didi

ios - 有什么方法可以在 SwiftUI 中使用 @ViewBuilder 创建/提取 View 数组

转载 作者:行者123 更新时间:2023-12-03 15:21:05 25 4
gpt4 key购买 nike

我正在尝试创建一个简单的 struct接受一个 View 数组并返回一个普通的 VStack包含这些 View ,但它们都是对角堆叠的。
代码:

struct LeaningTower<Content: View>: View {
var views: [Content]
var body: some View {
VStack {
ForEach(0..<views.count) { index in
self.views[index]
.offset(x: CGFloat(index * 30))
}
}
}
}
现在这很好用,但每当我不得不调用它时,我总是很生气:
LeaningTower(views: [Text("Something 1"), Text("Something 2"), Text("Something 3")])
在这样的数组中列出 View 对我来说似乎非常奇怪,所以我想知道是否有一种方法可以使用 @ViewBuilder调用我的 LeaningTower像这样的结构:
LeaningTower {  // Same way how you would create a regular VStack
Text("Something 1")
Text("Something 2")
Text("Something 3")
// And then have all of these Text's in my 'views' array
}
如果有办法使用 @ViewBuilder要创建/提取 View 数组,请告诉我。
(即使无法使用 @ViewBuilder 字面上任何使它看起来更整洁的东西都会有很大帮助)

最佳答案

您很少需要从 中提取 View 。数组 .如果您只是想通过 @ViewBuilder将内容放入 View 中,您可以简单地执行以下操作:

struct ContentView: View {
var body: some View {
VStackReplica {
Text("1st")
Text("2nd")
Text("3rd")
}
}
}

struct VStackReplica<Content: View>: View {
@ViewBuilder let content: () -> Content

var body: some View {
VStack(content: content)
}
}
如果这对您的用例来说还不够,请参见下文。

我有一个通用版本,所以不需要为不同长度的元组制作多个初始化器。此外, View 可以是任何你想要的(你不会被限制为每个 View 都是相同的类型)。
您可以在 GeorgeElsham/ViewExtractor 找到我为此制作的 Swift 包。 .这包含的不仅仅是这个答案中的内容,因为这个答案只是一个简化的基本版本。由于代码与此答案略有不同,因此请阅读 README.md首先举个例子。
回到答案,示例用法:
struct ContentView: View {

var body: some View {
LeaningTower {
Text("Something 1")
Text("Something 2")
Text("Something 3")
Image(systemName: "circle")
}
}
}
你的观点的定义:
struct LeaningTower: View {
private let views: [AnyView]

init<Views>(@ViewBuilder content: @escaping () -> TupleView<Views>) {
views = content().getViews
}

var body: some View {
VStack {
ForEach(views.indices) { index in
views[index]
.offset(x: CGFloat(index * 30))
}
}
}
}
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)
}
}
结果:
Result

关于ios - 有什么方法可以在 SwiftUI 中使用 @ViewBuilder 创建/提取 View 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62730374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com