I want to create a swiping TabView with PageTabViewStyle, each tab will show String content from a Firestore document.
like this:
I succeed to use ForEach to show the contents in a VStack
But when I use ForEach to show the contents in a TabView
I got “Thread 1: Fatal error: Index out of range” but can’t find the cause yet
This is the code of the TabView:
import SwiftUI
struct CardListView: View {
@EnvironmentObject var FService: MyFirebaseService
@EnvironmentObject var CardListVM: CardsViewModel
var colors: [Color] = [ .orange, .green, .yellow, .pink, .purple]
var body: some View {
TabView(){
ForEach(CardListVM.Cards){ item in
ZStack{
Rectangle()
.fill(colors.randomElement() ?? Color.yellow)
.frame(width: nil, height: 120)
.cornerRadius(10)
.padding(.horizontal, 10)
.padding(.vertical, 15)
ScrollView{
Text(item.content)
}
.frame(width: nil, height: 100)
.padding(.horizontal, 20)
.padding(.vertical, 25)
}
}
}
.tabViewStyle(PageTabViewStyle())
.onAppear {
CardListVM.getCards()
}
}
}
This is the fetch data code
import Foundation
import Firebase
import FirebaseFirestoreSwift
class CardsViewModel: ObservableObject{
@Published var Cards = [Card]()
func getCards(){
let db = Firestore.firestore()
let collection = db.collection("Card")
collection.whereField("userID", isEqualTo: Auth.auth().currentUser?.uid)
.getDocuments { QuerySnapshot, Error in
if let ErrorUW = Error {
print("Error: \(ErrorUW)")
} else {
for document in QuerySnapshot!.documents{
do {
let object = try document.data(as: Card.self)
self.Cards.append(object!)
} catch {
print("could not parse doc data")
}
}
}
}
}
}
Model
import Foundation
import Firebase
import FirebaseFirestoreSwift
struct Card: Identifiable, Codable{
@DocumentID var id: String?
var content: String
var userID: String
var category: String
}
This is when I use VStack, there are no Index out of range issue
import SwiftUI
struct CardListView: View {
@EnvironmentObject var FService: MyFirebaseService
@EnvironmentObject var CardListVM: CardsViewModel
var colors: [Color] = [ .orange, .green, .yellow, .pink, .purple].shuffled()
var body: some View {
VStack{
ForEach(CardListVM.Cards){ item in
ZStack{
Rectangle()
.fill(colors.randomElement() ?? Color.yellow)
.frame(width: nil, height: 120)
.cornerRadius(10)
.padding(.horizontal, 10)
.padding(.vertical, 15)
ScrollView{
Text(item.content)
}
.frame(width: nil, height: 100)
.padding(.horizontal, 20)
.padding(.vertical, 25)
}
}
}
.onAppear {
CardListVM.getCards()
}
}
}