【Swift UI】List構造体の使い方!見た目や余白のカスタマイズ
この記事からわかること
- Swift UIのList構造体の使い方
- デザインや余白の変更方法
- 1行ごと区切り線や見た目の変更方法
- リストを複数選択ボタンの実装方法
- 更新インジケータを表示させる方法
- 余白を調整する方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
SwiftUIで簡単にリスト形式のビューを実装できるList構造体
の使い方をまとめていきます。
List構造体とは?
Swift UIフレームワークで以下のようなリスト形式のビューを簡単に実装できるのがList構造体
です。複数のデータを見やすく管理するのに適しており、データ数が多い場合でも自動でスクロールビューにしてくれるのでデータ数を意識する必要がなくなります。
UIKitフレームワークではUITableView
クラスを使用することでリスト形式のビューを実装できますが使用方法は異なります。
使い方
使い方は簡単でList構造体の中にリスト形式で表示させたいビューを渡すだけです。設置するビューはText
でもButton
でもOKです。
import SwiftUI
struct ContentView: View {
var body: some View {
List{
Text("要素1")
Text("要素2")
Text("要素3")
}
}
}
中に複数のビューを設置することでリスト形式になります。
配列のレンジを取得して表示する
List構造体
のデータに配列を使用したい場合は配列.indices
で「0..<配列の要素数」のレンジを取得できます。indexに格納されるのは実際の要素の値ではなく0〜配列の要素数までの数値なので配列[index]としてindex番目の要素を取り出す点に注意してください。
struct ContentView: View {
let langs = ["HTML", "PHP", "Swift"]
var body: some View {
List(langs.indices, id:\.self){ index in
Text(langs[index])
}
}
}
配列内の要素が文字列や数値の場合はこの方法が一番手っ取り早いです。
ForEachで配列をデータに使用する
ForEach
を使用することでも配列内の要素を表示させることが可能です。こちらの場合は要素に直接アクセスできます。
List{
ForEach(langs, id:\.self){ item in
Text(item)
}
}
イニシャライザで配列をデータに使用する
配列内の要素が構造体やクラスなどの場合はForEach
を使用せずにList構造体のイニシャライザを使用して配列を取り出すことも可能です。その場合は配列内の要素がIdentifiable
プロトコルに準拠している必要があります。
class User:Identifiable {
let id:UUID = UUID()
var name: String = ""
init(name: String) {
self.name = name
}
}
struct ContentView: View {
let users = [User(name: "John"),User(name: "Michael"),User(name: "Johnny")]
var body: some View {
List(users){ user in
Text(user.name)
}
}
}
リストのスタイルを変更する
List構造体
では見た目をカスタマイズするためのモディファイアが数多く用意されています。
listStyle
モディファイアを使用することでリストのスタイルを変更できます。引数にはListStyleプロトコルの任意の値を渡します。
struct DefaultListStyle // デフォルト
struct BorderedListStyle // 標準枠 macOS
struct CarouselListStyle // カルーセル watchOS
struct EllipticalListStyle // 楕円 watchOS
struct GroupedListStyle // グループ化 iOS iPadOS Mac Catalyst TVOS
struct InsetListStyle // 差し込み iOS iPadOS macOS Mac Catalyst
struct InsetGroupedListStyle // 差し込みグループ化 iOS iPadOS Mac Catalyst
struct PlainListStyle // プレーン iOS iPadOS Mac Catalyst TVOS watchOS
struct SidebarListStyle // サイドバー iOS iPadOS macOS Mac Catalyst
引数として渡すのはタイププロパティとして定義されている値です。iOSでの例をみていきます。
automatic: DefaultListStyle
通常のスタイルです。左右に余白があります。
.listStyle(.automatic)
grouped: GroupedListStyle
左右の余白がなくなり画面いっぱいに広がります。
.listStyle(.grouped)
inset: InsetListStyle
背景色がなくなり、ビューに差し込まれるスタイルです。
.listStyle(.inset)
見出しをつける
Section
構造体を使用することでデータリストに見出しをつけることができます。Section(header:)
にヘッダーとして表示させたい文字列を渡します。渡した文字列は強制的に大文字に変換されてしまうようです。
List{
Section(header:Text("datalist")) {
Text("要素1")
Text("要素2")
Text("要素3")
}
}
1行ごとのカスタマイズ
リストの1行1行に対するカスタマイズも柔軟に行えるようにさまざまなモディファイアが用意されています。用途別に見ていきます。
区切り線を非表示にする
1行ごとの区切り線を非表示にするにはlistRowSeparator
モディファイアを使用します。
.listRowSeparator(.hidden)
区切り線の色を変える
1行ごとの区切り線の色を変更するにはlistRowSeparatorTint
モディファイアを使用します。
.listRowSeparatorTint(.orange)
中に指定することで1行1行を別々の色に変更することも可能です。
Text("要素1").listRowSeparatorTint(.red)
Text("要素2").listRowSeparatorTint(.blue)
Text("要素3").listRowSeparatorTint(.green)
背景色を変更する
1行ごとの背景色を変更するにはlistRowBackground
モディファイアを使用します。
.listRowBackground(Color.orange)
行だけでなく全体を変更する方法もあるので詳細は以下の記事を参考にしてください。
余白を調整する
1行ごとの余白を調整更するにはlistRowInsets
モディファイアを使用します。
.listRowInsets(EdgeInsets(top: 30, leading: 10, bottom: 30, trailing: 10))
リストの複数選択するボタンの実装
表示しているデータにチェックボタンをを実装し、複数選択可能なリストを作成するには引数selection
にバインディングした変数を渡し、toolbar
モディファイアにEditButton
構造体を渡します。
struct ContentView: View {
@State private var multiSelection = Set<UUID>()
let users = [User(name: "John"),User(name: "Michael"),User(name: "Johnny")]
var body: some View {
VStack{
NavigationView {
List(users,selection: $multiSelection){ user in
Text(user.name)
}.toolbar { EditButton() }
}
Text("\(multiSelection.count)個")
}
}
}
更新インジケータを表示させる
リストを下にプルダウンした際に更新インジケータを表示させることも可能です。そのためにはrefreshable(action:)
を使用して以下のように記述します。
List(users){ user in
Text(user.name)
}
.refreshable {
// await 更新処理
}
リストの1行を長押しでメニューを表示させる
contextMenu
を使用して1行を長押しすることでメニューを表示させることが可能です。
struct ContentView: View {
let langs = ["HTML", "PHP", "Swift","kotlin"]
var body: some View {
List(langs.indices, id:\.self){ index in
Text(langs[index])
.contextMenu {
Button {
} label: {
Label("お気に入り", systemImage: "star")
}
}
}
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。