SwiftUIのSectionとListとForEachを理解したい

Howto

SwiftUIはAppleが開発したUIツールキットで、ユーザーインターフェースを作成します。この記事では、SwiftUIの基本的な要素であるSectionList、そしてForEachについて詳しく解説します。

SwiftUIのSectionとListとForEachを理解したい

Section{
    List {
        ForEach(1..<1200) { number in
            Text("\(number)")
        }
    }
}

ForEachの基本

まずはForEachから見ていきましょう。ForEachは、コレクションの各要素に対してビューを生成します。以下のコードは、1から1199までの数字をリストで表示する例です。

ForEach(1..<1200) { number in
    Text("\(number)")
}

ここで重要なのは、ForEachがループするコレクションの各要素は一意のIDを持つ必要があるということです。しかし、整数の範囲(例えば 1..<1200)はすでに一意なID(その値自体)を持っているため、明示的にIDを指定する必要はありません。

ForEach

struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable

https://developer.apple.com/documentation/swiftui/foreach : 公式

ForEachを使うときは<Data, ID, Content>この並びを常に意識しておきたいです。

ForEachは、SwiftUIの構造体で、コレクションの各要素に対してビューを生成します。これは、SwiftUIの構文を活用して、コレクションのデータを直接ビューにマッピングするためのものです。

ID

しかし、自分で定義した型の配列をForEachでループする場合、その型がIdentifiableプロトコルに準拠しているか、またはid:パラメータで一意なIDを提供する必要があります。

例えば、以下のような型の配列をループする場合です。

struct Item: Identifiable {
    let id: Int
    let name: String
}

struct ContentView: View {
    let items = [Item(id: 1, name: "Item 1"), Item(id: 2, name: "Item 2"), Item(id: 3, name: "Item 3")]

    var body: some View {
        List {
            ForEach(items) { item in
                Text(item.name)
            }
        }
    }
}

この例では、Item型はIdentifiableプロトコルに準拠しており、idプロパティを持っています。そのため、ForEachは各アイテムのidを使用してビューを一意に識別できます。

以上が、SwiftUIのForEachについての詳しい解説です。

List

Listは、SwiftUIの構造体で、一連の行を表示するためのコンテナビューです。iOSで言うところのUITableViewに相当します。Listは、その子ビューを垂直にスクロール可能なリストとして表示します。

以下に、基本的な使用例を示します。

struct ContentView: View {
    var body: some View {
        List {
            Text("Row 1")
            Text("Row 2")
            Text("Row 3")
        }
    }
}

このコードでは、3つのTextビューがList内に配置されています。結果として、”Row 1″、”Row 2″、”Row 3″というテキストが垂直にスクロール可能なリストに表示されます。

Listは、ForEachと組み合わせることで、コレクションのデータを直接ビューにマッピングすることができます。これにより、動的なリストを簡単に作成することができます。

struct ContentView: View {
    var body: some View {
        List {
            ForEach(1..<12) { number in
                Text("Row \(number)")
            }
        }
    }
}

このコードでは、1..<12という範囲をForEachに渡し、その結果をListに表示しています。結果として、”Row 1″から”Row 11″までのテキストがリストに表示されます。

また、ListSectionを使用して内容をグループ化することもできます。これにより、セクションヘッダーやフッターを持つリストを作成することができます。

以上が、SwiftUIのListについての詳しい解説です。

このコードをコピペすれば分かりますが11個目のSectionで先程のエラーが発生します。

VStackなど他のViewに分けることで回避出来ます。

Section

Sectionは、SwiftUIの構造体で、ビューをグループ化するためのコンテナビューです。特にList内で使用されることが多く、リストのセクションを作成するために使用します。

以下に、基本的な使用例を示します。

struct ContentView: View {
    var body: some View {
        List {
            Section(header: Text("Section 1")) {
                Text("Row 1")
                Text("Row 2")
            }
            Section(header: Text("Section 2")) {
                Text("Row 3")
                Text("Row 4")
            }
        }
    }
}

このコードでは、2つのSectionList内に配置されています。各Sectionはヘッダーテキストと2つのTextビューを持っています。結果として、”Section 1″と”Section 2″というヘッダーを持つ2つのセクションがリストに表示されます。

以上が、SwiftUIのSectionについての詳しい解説です。

Viewの制約

次にSectionについて見ていきましょう。Sectionは、ビューをグループ化するためのコンテナです。しかし、SwiftUIでは一つのビュー内に10個以上の子ビューを持つことができません。これを超えると「Extra argument in call」というエラーが出ます。

しかし、この制約を回避する方法があります。それは、10個ずつ別のViewに入れてしまうことです。以下のコードは、それぞれのSectionListを配置し、その中にForEachを使用しています。

import SwiftUI

struct ContentView: View {
    var body: some View {
        Section{
            List {
                //                  Data  ID
                ForEach(1..<1200) { number in
                    //              Content
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
        Section{ // エラー Extra argument in call
            List {
                ForEach(1..<1200) { number in
                    Text("\(number)")
                }
            }
        }
    }
}

コメント

タイトルとURLをコピーしました