「ForEachでリスト表示したいけど、id: \.self
ってどういう意味?」
初めてSwiftUIに触れた人がつまずきがちなポイントですよね。
実はこの id: \.self
、SwiftUIでリストやビューを繰り返し表示するうえでとてもよく使われる書き方なんです。
でも、何をしているかピンとこない人も多いはず。
この記事では、そんな id: \.self
の意味・使い方・よくある例をSwiftUI初心者の方にもわかるように丁寧に解説していきます!
id: .self ってなに?
SwiftUIの ForEach
を使って配列などのデータを一覧表示するとき、Swiftは「このデータのどこをIDにするか」を知る必要があります。
たとえば:
1 2 |
let fruits = ["りんご", "バナナ", "みかん"] |
この配列を ForEach
で表示したいときは、こんな風に書きます👇
1 2 3 4 |
ForEach(fruits, id: \.self) { fruit in Text(fruit) } |
この id: \.self
が、「この配列の中にある "りんご" や "バナナ" や "みかん" といった文字列そのものをIDとして使うよ」という意味なんです。
つまり、各要素(ここでは果物の名前)がそのまま一意な識別子(ID)として扱われるということです。
そのため、同じ文字列が複数あるとIDが重複してしまってエラーになるので注意が必要です。
そもそも「IDって何のために必要なの?」
SwiftUIではリストなどを更新したときにどの要素がどのビューと対応しているかを判断する必要があります。
これをしないと、
- 「あれ?アイテム入れ替えたのにアニメーションされない…」
- 「削除したのに表示がバグる…」
みたいな問題が起きることも。
そのため、SwiftUIは「このデータのどの部分をIDとして使えばいいの?」と常に聞いてきます。
その答えとして渡すのが id: \.self
や id: \.id
なんです。
具体例①:文字列の配列に対して使う場合
1 2 3 4 5 6 7 8 9 10 |
let animals = ["ねこ", "いぬ", "うさぎ"] var body: some View { List { ForEach(animals, id: \.self) { animal in Text(animal) } } } |
animals
は [String]
の配列なので、各要素("ねこ" など)をIDとして使っています。
具体例②:構造体の配列なら .id を使うことも
たとえばこんな構造体があるとします。
1 2 3 4 5 |
struct Book: Identifiable { let id: UUID let title: String } |
このときは id: \.id
を使ったほうが自然です:
1 2 3 4 5 6 7 8 9 |
let books = [ Book(id: UUID(), title: "Swift入門"), Book(id: UUID(), title: "iOS開発ガイド") ] ForEach(books, id: \.id) { book in Text(book.title) } |
でも、もし Identifiable
プロトコルに準拠していれば、id:
を省略してもOK!
1 2 3 4 |
ForEach(books) { book in Text(book.title) } |
Swiftが自動で .id
を使ってくれます。
具体例③:ユニークじゃないとエラーになる
先ほど注意点として挙げましたが、id: \.self
を使うときはすべての要素がユニーク(重複していない)である必要があります。
たとえばこんな配列です。
1 2 |
let colors = ["赤", "青", "赤"] |
これで id: \.self
を使うと…
1 2 3 4 |
ForEach(colors, id: \.self) { color in Text(color) } |
→ エラーになります!
「赤」が2回出てくるので、IDがかぶってしまうためです。
こんなときは別にユニークなIDを自分でつけるようにしましょう:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
struct ColorItem: Identifiable { let id = UUID() let name: String } let colorItems = [ ColorItem(name: "赤"), ColorItem(name: "青"), ColorItem(name: "赤") ] ForEach(colorItems) { item in Text(item.name) } |
まとめ
id: \.self
は「この要素そのものをIDとして使うよ」という意味- SwiftUIの
ForEach
では、データのどこをIDにするか指定する必要がある - 要素がユニーク(重複なし)であれば
\.self
を使える - 構造体で
Identifiable
を使うとid:
を省略できて便利!
SwiftUIの ForEach
を使いこなすうえで、この id
の考え方はとても大事なので、ぜひ覚えておいてくださいね!