SwiftUI 如何动态添加 VStack、HStack、List 的元素? [英] How does SwiftUI dynamically add elements of VStack, HStack, and List?
问题描述
以VStack为例:
VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
}
我向 VStack 添加了 10 个矩形.到目前为止似乎没有问题:画布
I added 10 Rectangles to VStack. So far there seems to be no problem:  Canvas
然而我添加了另一个矩形然后报错:Extra argument in call
However I add another Rectangles then report an error: Extra argument in call
VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
}
这意味着 VStack、HStack 和 List 的构造函数只能接受 10 个参数,所以我将策略更改为使用嵌套 VStack:
This means that the constructors of VStack, HStack and List can only accept 10 arguments, so I changed the strategy to use nested VStack:
VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
}
}
这样可以突破VStack只能有10个元素的限制,所以我写了一个函数,根据用户输入动态增加Rectangle的总数:
This can break through the limitation that VStack can only have ten elements, so I wrote a function to dynamically increased the total number of Rectangles based on user input:
private func createRectangles(rectCount: UInt) -> some View {
func createRectangles(_ i: UInt) -> some View {
if i <= rectCount {
return VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
createRectangles(i + 1)
}
} else {
return VStack {
Rectangle()
}
}
}
return createRectangles(1)
}
反对!!!报错:函数声明了一个不透明的返回类型,但其主体中的返回语句没有匹配的底层类型
Opos!!! Report an error: Function declares an opaque return type, but the return statements in its body do not have matching underlying types
有人知道解决办法吗?
推荐答案
在这种情况下最简单的就是使用类型擦除,如下所示(使用 Xcode 11.4/iOS 13.4 测试)
The simplest in this case is just to use type erasure, like below (tested with Xcode 11.4 / iOS 13.4)
private func createRectangles(rectCount: UInt) -> some View {
func createRectangles(_ i: UInt) -> some View {
if i <= rectCount {
return AnyView(VStack {
Rectangle().size(CGSize(width: 20, height: 20)).fill(Color.green).frame(width: 20, height: 20)
createRectangles(i + 1)
})
} else {
return AnyView(VStack {
Rectangle()
})
}
}
return createRectangles(1)
}
这篇关于SwiftUI 如何动态添加 VStack、HStack、List 的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!