我从一个干净的项目开始,在VStack中添加了5个按钮和5个间隔,一切都很好。当我在底部添加第6个spacer时,代码突然不会编译并显示错误:“对成员'buildBlock()'的引用不明确”。
是什么导致此错误?这是与SwiftUI相关的错误吗?还是功能?这不是我第一次注意到VStack或HStack的条目数受到限制,这附近是否有一些文档?
不是完全可以激发信心,我应该切换回UIKit吗?
答案 0 :(得分:1)
SwiftUI使用ViewBuilder
来构建构成许多SwiftUI视图的视图,例如VStack
,HStack
,List
等。如果您看一下{ {3}}文档中,您将看到buildBlock
函数具有许多副本,每个副本具有不同数量的视图作为参数。具有最多视图数量的功能仅可容纳10个视图,这就是为什么您看到所观察到的限制的原因。解决此问题的一种方法是使用Group
:
VStack {
Group {
Text("Placeholder 0")
Text("Placeholder 1")
Text("Placeholder 2")
Text("Placeholder 3")
Text("Placeholder 4")
Text("Placeholder 5")
Text("Placeholder 6")
Text("Placeholder 7")
Text("Placeholder 8")
Text("Placeholder 9")
}
Group {
Text("Other Placeholder 10")
Text("Other Placeholder 11")
Text("Other Placeholder 12")
Text("Other Placeholder 13")
Text("Other Placeholder 14")
Text("Other Placeholder 15")
Text("Other Placeholder 16")
Text("Other Placeholder 17")
Text("Other Placeholder 18")
Text("Other Placeholder 19")
}
}
尽管如果您想要20个彼此非常相似的视图,建议您使用ForEach
之类的方法,以免使视图过于膨胀。仅当> 10个视图确实是唯一的时,才应使用上述解决方法。即便如此,更SwiftUI-y的方法是将这些视图拆分为更小的视图:
VStack {
SingleDigitPlaceholders()
TeensPlaceholders()
}
struct SingleDigitPlaceholders: View {
var body: some View {
ForEach(0..<10) { i in
Text("Placeholder \(i)")
}
}
}
struct TeensPlaceholders: View {
var body: some View {
ForEach(10..<20) { i in
Text("Other Placeholder \(i)")
}
}
}
当然,在此特定示例中,您只能在原始视图中具有两个ForEach
,但是在更复杂的情况下,问题仍然存在。例如,在具有许多元素的表单中(例如,在工作申请表中:名字,姓氏,地址,电话号码文本字段,教育下拉菜单,日期字段等),您仍然可以将一个视图拆分为较小的组件(在工作申请示例中-个人信息视图,教育信息视图等)。
答案 1 :(得分:0)
VStack
中最多可以有10个孩子(以及ZStack
,HStack
等)。严格来说,这与它们的实现以及@ViewBuilder
闭包的实现有关。请看下面的界面(您可以通过xCode找到它们,为了使其更具可读性,我对其进行了一些简化):
public struct ViewBuilder {
/// Builds an empty view from an block containing no statements, `{ }`.
public static func buildBlock() -> EmptyView
/// Passes a single view written as a child view (e..g, `{ Text("Hello") }`) through
/// unmodified.
public static func buildBlock<Content>(_ content: Content) -> Content where Content : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1>(_ c0: C0, _ c1: C1) -> TupleView<(C0, C1)> where C0 : View, C1 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2>(_ c0: C0, _ c1: C1, _ c2: C2) -> TupleView<(C0, C1, C2)> where C0 : View, C1 : View, C2 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3) -> TupleView<(C0, C1, C2, C3)> where C0 : View, C1 : View, C2 : View, C3 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4) -> TupleView<(C0, C1, C2, C3, C4)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4, C5>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5) -> TupleView<(C0, C1, C2, C3, C4, C5)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4, C5, C6>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6) -> TupleView<(C0, C1, C2, C3, C4, C5, C6)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View
}
extension ViewBuilder {
public static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9>(_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9)> where C0 : View, C1 : View, C2 : View, C3 : View, C4 : View, C5 : View, C6 : View, C7 : View, C8 : View, C9 : View
}
您可以看到,最多可以有10个孩子来建立这种视图。每个buildBlock
方法都将确切数量的视图用作参数。这是因为@ViewBuilder
闭包,至少目前不支持可变参数。
一种解决方法可以是:
struct ContentView: View {
var body: some View {
VStack {
Group {
//10 views here
}
Group {
//10 views here
}
}
}
}
答案 2 :(得分:0)
在我的视图周围添加组后,我有 6 个视图,我仍然在调用错误中收到 Extra 参数。
这就是我为修复错误所做的。
struct ContentView: View {
var body: some View {
VStack {
Group {
//3 views here
}
Group {
//3 views here
}
}
}
}