|
1 | 1 | import SwiftUI |
2 | 2 |
|
3 | | -public struct IndexedForEach<Element, Content>: View where Content: View { |
| 3 | +public struct IndexedForEach<Element, ID: Hashable, Content: View>: View { |
4 | 4 |
|
5 | | - let data: Array<Element> |
| 5 | + private let data: [Element] |
6 | 6 |
|
7 | | - let content: (Array<Element>.Index, Element) -> Content |
| 7 | + private let content: (Array<Element>.Index, Element) -> Content |
8 | 8 |
|
9 | | - public init(data: Array<Element>, @ViewBuilder content: @escaping (Array<Element>.Index, Element) -> Content) { |
| 9 | + private let id: KeyPath<IndexedArray<Element>.Element, ID> |
| 10 | + |
| 11 | + public init( |
| 12 | + _ data: [Element], |
| 13 | + @ViewBuilder content: @escaping (Array<Element>.Index, Element) -> Content |
| 14 | + ) where Element: Identifiable, ID == Element.ID { |
| 15 | + |
| 16 | + self.data = data |
| 17 | + self.content = content |
| 18 | + self.id = \.1.id |
| 19 | + } |
| 20 | + |
| 21 | + public init( |
| 22 | + _ data: [Element], |
| 23 | + id: KeyPath<Element, ID>, |
| 24 | + @ViewBuilder content: @escaping (Array<Element>.Index, Element) -> Content |
| 25 | + ) where Data: RandomAccessCollection, ID: Hashable { |
10 | 26 | self.data = data |
| 27 | + self.id = (\IndexedArray<Element>.Element.1).appending(path: id) |
11 | 28 | self.content = content |
12 | 29 | } |
13 | 30 |
|
14 | 31 | public var body: some View { |
15 | | - ForEach(IndexedArray.init(base: data), id: \.0) { e in |
| 32 | + ForEach(IndexedArray.init(base: data), id: id) { e in |
16 | 33 | content(e.0, e.1) |
17 | 34 | } |
18 | 35 | } |
@@ -70,10 +87,26 @@ struct IndexedArray<SourceElement>: RandomAccessCollection { |
70 | 87 |
|
71 | 88 | } |
72 | 89 |
|
| 90 | +#if DEBUG |
| 91 | + |
| 92 | +struct Item: Identifiable { |
| 93 | + let id: Int |
| 94 | +} |
| 95 | + |
73 | 96 | #Preview { |
74 | 97 | VStack { |
75 | | - IndexedForEach(data: [1, 2, 3]) { index, element in |
| 98 | + IndexedForEach([1, 2, 3], id: \.self) { index, element in |
| 99 | + Text("\(index): \(element)") |
| 100 | + } |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | +#Preview { |
| 105 | + VStack { |
| 106 | + IndexedForEach.init([Item(id: 0)]) { index, element in |
76 | 107 | Text("\(index): \(element)") |
77 | 108 | } |
78 | 109 | } |
79 | 110 | } |
| 111 | + |
| 112 | +#endif |
0 commit comments