リストを下に引っ張って更新する「Pull to Refresh」は、多くのアプリで採用されている UI パターンです。SwiftUI では refreshable モディファイアを使って簡単に実装できます。
refreshable の基本
refreshable モディファイアを List に適用するだけで、Pull to Refresh 機能が有効になります。
struct ContentView: View { @State private var items = ["項目1", "項目2", "項目3"] var body: some View { List(items, id: \.self) { item in Text(item) } .refreshable { // 更新処理 await loadData() } } func loadData() async { // API からデータを取得するなど try? await Task.sleep(nanoseconds: 1_000_000_000) // 1秒待機 items.append("新しい項目") } }
refreshable のクロージャは async コンテキストで実行されるため、await を使った非同期処理が可能です。更新インジケーターは処理が完了するまで自動的に表示されます。
API からデータを取得する例
実践的な例として、API からデータを取得してリストを更新するパターンを見てみましょう。
struct Article: Identifiable, Codable { let id: Int let title: String } struct ArticleListView: View { @State private var articles: [Article] = [] @State private var isLoading = true var body: some View { NavigationStack { List(articles) { article in Text(article.title) } .refreshable { await fetchArticles() } .overlay { if isLoading { ProgressView() } } .navigationTitle("記事一覧") .task { await fetchArticles() } } } func fetchArticles() async { defer { isLoading = false } guard let url = URL(string: "https://api.example.com/articles") else { return } do { let (data, _) = try await URLSession.shared.data(from: url) articles = try JSONDecoder().decode([Article].self, from: data) } catch { print("Error: \(error)") } } }
更新処理のポイント
(www.w3.org/2000/svg" viewBox="0 0 __viewBoxWidth__ __viewBoxHeight__" style="height: __height__;">"更新"iewBoxWidth__ __viewBoxHeight__" style="height: __height__;">)eight__" style="height: __height__;"> __height__;">{
awaitkcs {
fill: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
ll: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
refreshke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
?()stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
ox-dent-BX8RbKESldiWSkcs {
fill: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
} {
fill: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
bKESldiWSkcs {
fill: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
} fill: none;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
ne;
stroke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
}ke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
ke: #333;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
} stroke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
}troke-linecap: round;
stroke-miterlimit: 10;
stroke-width: 2px;
}
stroke-miterlimit: 10;
stroke-width: 2px;
}
stroke-miterlimit: 10;
stroke-width: 2px;
}
stroke-width: 2px;
}
`refreshable` はシンプルな API ながら、モダンなアプリに欠かせない Pull to Refresh 機能を手軽に実装できる強力なモディファイアです。