Home > front end >  How to Order An Array Of Data and Display It In That Order (Data On Firebase)
How to Order An Array Of Data and Display It In That Order (Data On Firebase)

Time:04-13

I have a project where I want to display badges (an image with a title) in a horizontal scroll view. The data for the badges is stored in a Firestore database. My code can fetch the data and show the badges in a horizontal scroll view. At the moment the badges are in a random order and I want to be able to sort them so they are in the correct order. For example:

Currently I have 4 badges, These include:

10k steps badge, 20k steps badge, 30k steps badge, 40k steps badge

This is the order I want them to be displayed in the horizontal scrollview however they are in a random order.

How can I order this data correctly? I am currently using a ForEach to Loop through the data.

My Model for the badges is as follows:

struct FitnessBadge: Identifiable {
    
    var id: String
    var fitness_badge_name: String
    var fitness_badge_details: String
    var fitness_badge_image: String
    
}

The View for the Badges is as follows:

struct FitnessBadgeView: View {
    
    var fitnessBadge: FitnessBadge
    
    var body: some View {
        
        VStack(alignment: .center){
            
            // Downloading Image From Web...
            WebImage(url: URL(string: fitnessBadge.fitness_badge_image))
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 150, height: 150)
                .cornerRadius(15)
            
            HStack(spacing: 8){
                
                Text(fitnessBadge.fitness_badge_name)
                    
                    .font(.title2)
                    .fontWeight(.bold)
                    .foregroundColor(.black)
            }
            HStack(alignment: .center){
                
                Text(fitnessBadge.fitness_badge_details)
                    .font(.subheadline)
                    .foregroundColor(.gray)
                    .lineLimit(2)

                Spacer(minLength: 0)
            }
        }
        
    }
}

How the badges are being displayed in a scroll view is as follows:

ScrollView(.horizontal, showsIndicators: false, content: {
    
    VStack(alignment: .leading) {
    
    Text("Fitness Badges")
            .font(.title2)
            .fontWeight(.bold)
            .foregroundColor(.black)
            
    HStack(spacing: 10){
        
        ForEach(AchievementPageModel.filteredFitnessBadges){fitnessBadge in
            
            // Badge View...
            ZStack(alignment: Alignment(horizontal: .center, vertical: .top), content: {
                
                FitnessBadgeView(fitnessBadge: fitnessBadge)
                
                })
            }
        }
    }
})

This is the horizontal scroll view

I want it to go: 10k steps, 20k steps, 30k steps etc.

The AchievementPageModel.filteredFitnessBadges array is as follows:

class AchievementPageViewModel: NSObject, ObservableObject {
 
    // Fitness Badges Data...
    @Published var fitnessBadges: [FitnessBadge] = []
    
    @Published var filteredFitnessBadges: [FitnessBadge] = []
    
}

And the fetching data for the badges is as follows:

func fetchFitnessBadgeData(){
    
    let db = Firestore.firestore()
    
    db.collection("FitnessBadges").getDocuments { (snap, err) in
        
        guard let fitnessBadgeData = snap else{return}
        
        self.fitnessBadges = fitnessBadgeData.documents.compactMap({ (doc) -> FitnessBadge? in
            
            let id = doc.documentID
            let name = doc.get("fitness_badge_name") as! String
            let image = doc.get("fitness_badge_image") as! String
            let details = doc.get("fitness_badge_details") as! String
            
            return FitnessBadge(id: id, fitness_badge_name: name, fitness_badge_details: details, fitness_badge_image: image)
        })
        
        self.filteredFitnessBadges = self.fitnessBadges
    }
}

CodePudding user response:

In the view where badges are being displayed, replace:

ForEach(AchievementPageModel.filteredFitnessBadges)

with:

ForEach(AchievementPageModel.filteredFitnessBadges.sorted { $0.fitness_badge_name < $1.fitness_badge_name })

This will sort by the field fitness_badge_name. I have assumed that's the field that contains "10k", "20k"... if the key is another field, just replace the variable in the .sorted() function.

  • Related