SwiftUIでアプリを作成しているとList
を使用して何かの配列を一覧表示させることはよくあると思います。しかしその際に
Initializer ‘init(_:rowContent:)’ requires that ‘xxxx’ conform to ‘Identifiable’
というようなエラーが出たことはないでしょうか?このエラーを発生させないためにはIdentifiable
というものについての理解が必要になります。
今回はそのIdentifiable
について説明します。
Listで発生するエラーの意味
Identifiable
について語る前に、まずは上に書いたエラーの意味を確認しましょう。
和訳すると、「イニシャライザー init(_:rowContent:) は、xxxx が identifiable に準拠している必要があります。」という内容になります。
このエラーは例えば以下のような実装をすると発生します。
struct ContentView: View {
let rows = ["abc","def","ghi"]
var body: some View {
List(rows){ row in
Text(row)
}
}
}
ではこの実装はなぜエラーになってしまうのでしょう?
理由はList
の性質にあります。Listのような繰り返し処理でコンテンツを作った場合、そのコンテンツのデータを更新する必要が出た際にどのコンテンツを更新するのか、SwiftUI側がわからないといけないですよね。そのため、繰り返し処理で作成されるコンテンツには予めidを振ってあげる必要があるのです。
つまり上記のエラーが出たということは、そのidを振ることができないということを伝えているのです。
Identifiableの役割
Identifiableプロトコルに準拠した構造体は、idを持っている=idを振ることができる ということになります。idが振られることでSwiftUI側はどのコンテンツのデータを更新すればいいのかがわかるため、上記のようなエラーが発生しなくなります。
実装方法
それでは上のコードを、エラーが出ないように書き換えましょう。
struct ContentView: View {
let rows = [Row(id: 1, str: "abc"), Row(id: 2, str: "def"), Row(id: 3, str: "ghi")]
var body: some View {
List(rows){ row in
Text(row.str)
}
}
}
struct Row: Identifiable {
let id: Int
var str: String
}
先ほどList
で表示しようとしていたStringの配列は、Row
という構造体で定義するようにして、Row
はIdentifiable
に準拠し、idというプロパティを持つようにしました。
こうすることでSwiftUI側はプロパティidを使ってどのコンテンツを更新すればいいのかを判断できるようになります。
今回はidをIntで定義しましたが、一意性が保たれればStirngとかでも大丈夫です。
コメント