I'm still trying to get my head around Swift/SwiftUI, so apologies for what's likely a really simple question. Consider this simple SwiftUI file:
import SwiftUI
struct sampleStruct {
let entryID: Int // comes from the system
let name: String
}
struct TestView: View {
var listEntries = [sampleStruct(entryID: 301, name: "Pete"),
sampleStruct(entryID: 5003, name: "Taylor"),
sampleStruct(entryID: 13, name: "Suzie")]
var body: some View {
VStack{
ForEach(listEntries, id: \.entryID) { idx in
Text(idx.name)
}
}
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
}
}
Here's my question: I'm looking for a simple way to add the position of the element in the array to the text field. Ie instead of Pete, Taylor, Susie, I'd like to get:
1 Pete
2 Taylor
3 Suzie
I thought that this could do the trick:
...
VStack{
ForEach(listEntries, id: \.entryID) { idx in
Text( listEntries.firstIndex { $0.id == idx.entryID } )
Text(idx.name)
}
}
...
But, I'm getting the error "No exact matches in call to initializer".
Any help would be appreciated,
Philipp
The simplest approach would be to use enumerated()
, which returns a sequence of pairs (index and item):
struct TestView: View {
var listEntries = [sampleStruct(entryID: 301, name: "Pete"),
sampleStruct(entryID: 5003, name: "Taylor"),
sampleStruct(entryID: 13, name: "Suzie")]
var body: some View {
VStack{
ForEach(Array(listEntries.enumerated()), id: \.1.entryID) { (index,item) in
Text("\(index + 1) \(item.name)")
}
}
}
}
Note that for extremely large collections you might want a different approach for performance reasons, but for anything reasonably sized, this will work well. A quick and easy upgrade to it would be to used indexed()
from Swift Algorithms in place of .enumerated()
(you could omit the Array(...)
wrapper if you did this as well.
If for learning purposes you want to see what you'd have to do to adjust your original approach, you'd want to:
.entryID
instead of .id
, which doesn't exist on your modelfirstIndex
returns nil
String
One solution might look like this:
struct TestView: View {
var listEntries = [sampleStruct(entryID: 301, name: "Pete"),
sampleStruct(entryID: 5003, name: "Taylor"),
sampleStruct(entryID: 13, name: "Suzie")]
var body: some View {
VStack{
ForEach(listEntries, id: \.entryID) { item in
let index = listEntries.firstIndex { $0.entryID == item.entryID } ?? -1
Text("\(index + 1) \(item.name)")
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.