ForEach(output, id: \.self) { text in Text(text) .font(.system(.body, design: .monospaced)) .frame(maxWidth: .infinity, alignment: .leading) .foregroundColor(.white) ForEach(output.indices, id: \.self) { index in Text(output[index]) .font(.system(.body, design: .monospaced)) .frame(maxWidth: .infinity, alignment: .leading) .foregroundColor (index % 2 == 0 ? .white : .green) // var body: some View { ForEach(array.indices) { i in Text("\(self.array[i])") .onTapGesture { self.doSomething(index: i) } } } public struct ForEachWithIndex<Data: RandomAccessCollection, ID: Hashable, Content: View>: View { public var data: Data public var content: (_ index: Data.Index, _ element: Data.Element) -> Content var id: KeyPath<Data.Element, ID> public init(_ data: Data, id: KeyPath<Data.Element, ID>, content: @escaping (_ index: Data.Index, _ element: Data.Element) -> Content) { self.data = data self.id = id self.content = content } public var body: some View { ForEach( zip(self.data.indices, self.data).map { index, element in IndexInfo( index: index, id: self.id, element: element ) }, id: \.elementID ) { indexInfo in self.content(indexInfo.index, indexInfo.element) } } } extension ForEachWithIndex where ID == Data.Element.ID, Content: View, Data.Element: Identifiable { public init(_ data: Data, @ViewBuilder content: @escaping (_ index: Data.Index, _ element: Data.Element) -> Content) { self.init(data, id: \.id, content: content) } } extension ForEachWithIndex: DynamicViewContent where Content: View { } private struct IndexInfo<Index, Element, ID: Hashable>: Hashable { let index: Index let id: KeyPath<Element, ID> let element: Element var elementID: ID { self.element[keyPath: self.id] } static func == (_ lhs: IndexInfo, _ rhs: IndexInfo) -> Bool { lhs.elementID == rhs.elementID } func hash(into hasher: inout Hasher) { self.elementID.hash(into: &hasher) } }