Michel
Michel

Reputation: 11753

Conforming an array to Identifiable in SwiftUI

I have a little question about conforming to Identifiable in SwiftUI.

There are situations where we are required to have a given type MyType to conform to Identifiable.

But I am facing a case where I am required to have [MyType] (an array of MyType) to conform to Identifiable.

I have MyType already conforming to Identifiable. What should I do to also make [MyType] to conform to Identifiable?

Upvotes: 4

Views: 6186

Answers (2)

New Dev
New Dev

Reputation: 49590

You can write an extension to conform an Array to Identifiable.

Since extensions can't contain stored properties, and also because it makes sense that two arrays that are the "same" to also have the same id, you'd need to compute the id based on the contents of an array.

The simplest approach here is if you can conform your type to Hashable:

extension MyType: Hashable {}

This also makes [MyType] conform to Hashable, and since id could be any Hashable, you could use the array itself as its own id:

extension Array: Identifiable where Element: Hashable {
   public var id: Self { self }
}

Or, if you want, the id could be an Int:

extension Array: Identifiable where Element: Hashable {
   public var id: Int { self.hashValue }
}

Of course, you can do this just for your own type where Element == MyType, but that type would need to be public.

Upvotes: 7

aheze
aheze

Reputation: 30298

I suggest embedding [MyType] in a struct, then having the struct conform to Identifiable. Something like this:

struct MyType: Identifiable {
    let id = UUID()
}
struct Container: Identifiable {
    let id = UUID()
    var myTypes = [MyType]()
}

Usage:

struct ContentView: View {
    let containers = [
        Container(myTypes: [
            MyType(),
            MyType()
        ]),
        Container(myTypes: [
            MyType(),
            MyType(),
            MyType()
        ])
    ]
    
    var body: some View {

        /// no need for `id: \.self`
        ForEach(containers) { container in
            ...
        }
    }
}

Upvotes: 8

Related Questions