【SwiftUI】VStackでExtra argument in callの原因とエラー解決!ViewBuilder構造体とは

この記事からわかること

  • SwiftUIVStackで発生したエラー
  • Extra argument in call原因解決方法
  • ViewBuilder構造体とは?
  • buildBlockメソッドの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

エラー:Extra argument in callとは?

SwiftUIでアプリ開発中にVStackビューを縦に並べていた際に以下のようなエラーが発生しました。

発生したコード

struct ContentView: View {
    var body: some View {
        VStack {
            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
// 翻訳:呼び出しの余分な引数

このエラーは渡された引数の数が合わない際に発生するエラーのようです。今回はVStackの引数に11個のTextView構造体を渡したところ発生しました。

VStackの定義

おすすめ記事:【Swift UI】HStack/VStack/ZStackの違いと組み込む方法!LazyHStackの使い方

VStackの定義を見てみると3つの引数が定義されています。

@frozen  public struct VStack<Content> : View where Content : View {

  @inlinable  public init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder  content: () -> Content)
}

今回エラーが発生している引数はcontent部分です。ここはViewBuilder構造体のみを受け取ることになっています。

ここだけを見ると複数のビューを受け取れる理由がよくわかりません。これを解決するためにViewBuilder構造体の定義を見ていきます。

ViewBuilder構造体とは?

ViewBuilderとはクロージャからビューを構築するために使用される構造体です。VStackHStackなどをインスタンス化して使用する際は()ではなく{}を使用しているのもこのViewBuilderが関連してきています。

おすすめ記事:【Swift】クロージャとは?関数との違いとキャプチャの意味

ViewBuilderの定義を見てみるとbuildBlockメソッドが怪しそうです。

ViewBuilderの定義

@resultBuilder  public struct ViewBuilder {

static func buildBlock<Content>(_ content: Content) -> Content where Content : View

つまりVStackの引数に渡すViewBuilderのbuildBlockメソッドを使用してTextなどのビューを渡しているようです。なので以下のコードでも問題なく動作しました。

struct ContentView: View {
    var body: some View {
        VStack {
            ViewBuilder.buildBlock(
              Text("1")
          )
        }
    }
}

エラーの原因

先ほどは1つのビューを返す場合のメソッドでしたが、さらに以下のメソッドも定義されていました。引数にはC0〜C9までを受け取れるメソッドのようです。ContentsのCでしょうか?

そしてこの数が10個です。定義されていた最大の引数を保持していたのがこのメソッドだったのでViewBuilderでは最大10個のビューまでしかクロージャの中に含めることができないようです。

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個以上のビューを含める方法

ViewBuilder構造体に含めることができるビューが10個までと分かりましたが、それ以上のビューを含めることができないわけではありません。

ViewBuilder子ビューが10個までと言うことなのでHStackGroupなどで囲うことで10個以上のTextを表示させることが可能でした。

struct ContentView: View {
    var body: some View {
        VStack {
            HStack{
                Text("1")
                Text("2")
                Text("3")
            }
            Group{
                Text("4")
                Text("5")
                Text("6")
            }
            VStack{
                Text("7")
                Text("8")
                Text("9")
            }
            Text("10")
            Text("11")
        }
    }
}

私がSwift UI学習に使用した参考書

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index