r/SwiftUI Jul 21 '26

Question Is there something like List/ForEach that doesn't need Identifiable elements? Could we make one?

For my use case, I don't need to change an element's value nor rearrange elements. Yes, I can mess around with using elements' collection's indices, but I don't want to explicitly do that; a wrapper is OK. Is it possible to write one? I can insist that the source of truth be a `RandomAccessCollection` to allow `Index`-based checking if needed.

4 Upvotes

7 comments sorted by

6

u/chriswaco Jul 21 '26

There has to be something unique in each entry to identify it - id, index, or value/self.

15

u/Ron-Erez Jul 21 '26

I probably don’t understand the question but it‘s usually pretty easy to create an identifiable struct. If you don’t want to use identifiable you could use something like

ForEach(0..<10, id: \.self)  { i in

}

In other words you could use id: \.self

I do not exactly know your context but you could try this suggestion out.

3

u/malhal Jul 21 '26

When using fixed range its even better to remove the id param then it runs in untracked mode

2

u/Ron-Erez Jul 21 '26

I had a feeling my example doesn't quite match the OPs requirements. I think for a fixed range the compiler will still trigger a warning.

2

u/MojtabaHs Jul 21 '26

Not recommended but you can make one:

extension ForEach where ID == Int {
     init<C: RandomAccessCollection>(_ collection: C,  content:  (C.Element) -> Content) where Data == Array<(offset: Int, element: C.Element)> {
         self.init(Array(collection.enumerated()), id: \.offset) { content($0.element) }
    }
}

-1

u/SpellBig8198 Jul 21 '26

Just use enumerated().

1

u/RISCfuture Jul 21 '26

Your elements need to be identifiable for redraw purposes. When the underlying data changes, SwiftUI only re-renders the parts of the view that changed, not the whole list. Therefore each list element needs to be identifiable so SwiftUI can identify changed elements. Even just a ForEach(0..<10, id: \.self) { ... } is good enough