Closed2

[SwiftUI]Listを詳しく知りたい我

ほへとほへと

以下を読む。

https://developer.apple.com/documentation/swiftui/list


概要

1 つの列に配置されたデータ行を表示するコンテナー。

・シンプルなリスト例

var body: some View {
    List {
        Text("A List Item")
        Text("A Second List Item")
        Text("A Third List Item")
    }
}

・動的にリスト例

より一般的には、基礎となるデータのコレクションからリストを動的に作成します。次の例は、Identifiable に準拠する Ocean 型の配列から単純なリストを作成する方法を示しています。

struct Ocean: Identifiable {
    let name: String
    let id = UUID()
}

private var oceans = [
    Ocean(name: "Pacific"),
    Ocean(name: "Atlantic"),
    Ocean(name: "Indian"),
    Ocean(name: "Southern"),
    Ocean(name: "Arctic")
]

var body: some View {
    List(oceans) {
        Text($0.name)
    }
}

・選択可能なリスト例

選択可能なListを生成するには、以下2つの条件が必要。
・引数(selection)に選択値を格納するプロパティを指定する。
・対象のViewを編集モードにする。

複数選択を可能にする場合は、編集ボタンをつける必要があるので注意。

タップまたはクリックで 1 つの選択を行うと、選択されたセルの外観が変わり、選択されていることを示します。タップ ジェスチャで複数の選択を有効にするには、editMode 値を変更するか、アプリのインターフェイスに EditButton を追加して、リストを編集モードにします。リストを編集モードにすると、リストの各リスト項目の横に円が表示されます。ユーザーが関連する項目を選択すると、円にチェックマークが表示されます。上記の例では、編集モード中にタイトルが [完了] に変わる [編集] ボタンを使用しています。

struct SearchView: View {
    @State private var searchText: String = ""
    @StateObject private var model: SearchModel = .init()
    // Int部分は適宜変える。この型重要!
    @State private var multiSelection = Set<Int>()

    var body: some View {
        NavigationStack {
            // selectionの指定。ここでタップされた行がバインドされる。
            List(model.repositories.items, selection: $multiSelection) {
                SearchViewCell(
                    title: $0.name,
                    description: $0.description
                )
            }
            .searchable(
                text: $searchText,
                prompt: "検索"
            )
            .onChange(of: searchText) { _, newValue in
                model.searchRepository(query: newValue)
            }
            // 複数選択する場合は、編集ボタンが必須。
            .toolbar { EditButton() }
        }
    }
}

以下も参考に!
https://capibara1969.com/3084/

・リフレッシュ例

標準の更新コントロールを使用してリストのコンテンツを更新可能にするには、refreshable(action:) 修飾子を使用します。次の例は、リストに標準の更新コントロールを追加する方法を示しています。ユーザーがリストの上部を下にドラッグすると、SwiftUI は更新コントロールを表示し、指定されたアクションを実行します。アクション クロージャ内で await 式を使用してデータを更新します。待機中の操作の間、更新インジケーターは表示されたままになります。

struct Ocean: Identifiable, Hashable {
     let name: String
     let id = UUID()
     let stats: [String: String]
 }

 class OceanStore: ObservableObject {
     @Published var oceans = [Ocean]()
     func loadStats() async {}
 }

 @EnvironmentObject var store: OceanStore

 var body: some View {
     NavigationView {
         List(store.oceans) { ocean in
             HStack {
                 Text(ocean.name)
                 StatsSummary(stats: ocean.stats) // A custom view for showing statistics.
             }
         }
         .refreshable {
             await store.loadStats()
         }
         .navigationTitle("Oceans")
     }
 }

refreshableについても調べてみる。

このビューを更新可能としてマークします。

nonisolated
func refreshable(action: @escaping () async -> Void) -> some View

ユーザーが更新を要求したときに SwiftUI が実行する非同期ハンドラー。このハンドラーを使用して、変更されたビューに表示されるモデル データの更新を開始します。ハンドラー内のすべての非同期呼び出しの前に await を使用します。

独自のビューにも更新機能を追加できます。その方法については、RefreshActionを参照してください。

https://developer.apple.com/documentation/swiftui/view/refreshable(action:)

・2次元リスト例

section毎にListを分けるのはいろんなところで使いそう。

struct ContentView: View {
    struct Sea: Hashable, Identifiable {
        let name: String
        let id = UUID()
    }

    struct OceanRegion: Identifiable {
        let name: String
        let seas: [Sea]
        let id = UUID()
    }

    private let oceanRegions: [OceanRegion] = [
        OceanRegion(name: "Pacific",
                    seas: [Sea(name: "Australasian Mediterranean"),
                           Sea(name: "Philippine"),
                           Sea(name: "Coral"),
                           Sea(name: "South China")]),
        OceanRegion(name: "Atlantic",
                    seas: [Sea(name: "American Mediterranean"),
                           Sea(name: "Sargasso"),
                           Sea(name: "Caribbean")]),
        OceanRegion(name: "Indian",
                    seas: [Sea(name: "Bay of Bengal")]),
        OceanRegion(name: "Southern",
                    seas: [Sea(name: "Weddell")]),
        OceanRegion(name: "Arctic",
                    seas: [Sea(name: "Greenland")])
    ]

    @State private var singleSelection: UUID?

    var body: some View {
        NavigationView {
            List(selection: $singleSelection) {
                ForEach(oceanRegions) { region in
                    Section(header: Text("Major \(region.name) Ocean Seas")) {
                        ForEach(region.seas) { sea in
                            Text(sea.name)
                        }
                    }
                }
            }
            .navigationTitle("Oceans and Seas")
        }
    }
}
このスクラップは4ヶ月前にクローズされました