Я собираюсь построить IndexedList
, который будет работать точно так же, как SwiftUI List
View, но обеспечивает закрытие с (element, index) -> RowContent
по сравнению с текущим (element) -> RowContent
.
Одна вещь, которую я я не нашел, как вы можете назначить init()
обобщение экземпляру класса, когда вы не знаете тип на уровне класса.
Если вы посмотрите на одну из List
подписи инициализации View, вы можете видеть, что он использует локальные дженерики:
public init<Data, RowContent>(_ data: Data, selection: Binding<Set<SelectionValue>>?, @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) where Content == ForEach<Data, Data.Element.ID, HStack<RowContent>>, Data : RandomAccessCollection, RowContent : View, Data.Element : Identifiable
Однако Data
является типом generi c на уровне метода init()
, как вы можете определить его на уровне класса, чтобы вы могли сделать self.data = data
?
Пробовал Data
и RandomAccessCollection
:
struct IndexedList<SelectionValue, Content>: View where SelectionValue: Hashable, Content: View {
let data: RandomAccessCollection // <- type issue
let selection: Binding<Set<SelectionValue>>?
let rowContent: (Data.Element) -> View // <- type issue
var body: some View {
let withIndex = self.data.enumerated().map({ $0 })
return List(withIndex, id: \.element.id) { index, element in
self.rowContent(index, element)
}
}
public init<Data, RowContent>(_ data: Data, selection: Binding<Set<SelectionValue>>?, @ViewBuilder rowContent: @escaping (Data.Element, index: number) -> RowContent) where Content == ForEach<Data, Data.Element.ID, HStack<RowContent>>, Data : RandomAccessCollection, RowContent : View, Data.Element : Identifiable {
self.data = data
self.selection = selection
self.rowContent = rowContent
}
}
Но это не работает!