SwiftUIが提供する各種ViewのContentClosure引数内には定義出来るViewの数が決まっており、最大で10個のViewを配置することが出来ます。
struct ContentView: View {
var body: some View {
HStack {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")
Text("10")
}
}
}
多くのケースでは10個も配置出来れば十分なのですが、稀に11個以上のViewを配置したいケースも出てきますがこれはコンパイルエラーとなります。
struct ContentView: View {
var body: some View {
HStack {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")
Text("10")
Text("11") // `Extra argument in call` というコンパイルエラーになる
}
}
}
なぜこのようなコンパイルエラーが発生するのかというとSwiftUIのContentClosureに複数のViewを配置した場合の実態はTupleView
となり、
Tuple内に定義出来るViewの数がデフォルトでは10個までしか定義されていないためです。
/**
以下のようにTuple内に配置出来るViewの数毎のI/Fが定義されており、これの最大数が10個となっています。
*/
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
}
型定義を見るとViewBuilderを拡張しているだけなので、より多くのViewを配置したい場合は独自にViewBuilderの型定義を追加すれば良いです。
/**
以下の要領で必要な数を内包するTupleViewを定義していけば良い。
*/
extension ViewBuilder {
static func buildBlock<C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10> (_ c0: C0, _ c1: C1, _ c2: C2, _ c3: C3, _ c4: C4, _ c5: C5, _ c6: C6, _ c7: C7, _ c8: C8, _ c9: C9, _ c10: C10) -> TupleView<(C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10)> where C0: View, C1: View, C2: View, C3: View, C4: View, C5: View, C6: View, C7: View, C8: View, C9: View, C10: View {
TupleView((c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10))
}
}
struct ContentView: View {
var body: some View {
HStack {
Text("1")
Text("2")
Text("3")
Text("4")
Text("5")
Text("6")
Text("7")
Text("8")
Text("9")
Text("10")
Text("11") // 上で11個を内包するTupleViewが定義されたので、ここでコンパイルエラーが発生しなくなる
}
}
}