【ざっくり解説】Identifiableとは?- Swiftを理解する

List

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という構造体で定義するようにして、RowIdentifiableに準拠し、idというプロパティを持つようにしました。

こうすることでSwiftUI側はプロパティidを使ってどのコンテンツを更新すればいいのかを判断できるようになります。

今回はidをIntで定義しましたが、一意性が保たれればStirngとかでも大丈夫です。

コメント