UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Section headers for a dynamic list

Forums > SwiftUI

Please, how can I create section headers for a dynamic list I'm fetching from Firestore. My model struct is:

struct MatchItem: Identifiable{
    var id: Int
    var localTeam: String
    var visitorTeam: String
    var minute: Int
    var status: String
    var timestamp: Date
    var league_id: Int
}

I have an array of MatchItem created thus:

var todaysLlist = [MatchItem]()

And my List is created like this:

List(todaysLlist){matchItem in
                    TodaysMatchItemCell(matchItem: matchItem)

                }
                .listStyle(PlainListStyle())

Please how can I group the array using the league_id property and create section headers in my list. Thank you very much.

1      

hi,

i would suggest first breaking out your todaysLlist into a dictionary, grouping by league_id:

let groups = Dictionary(grouping: todaysLlist, by: { $0.league_id })

the groups variable has the type [Int : [MatchItem]], where the keys of the dictionary are the values of league_id, and the values of the dictionary are arrays of MatchItems sharing the same league_id.

but you'll want to restructure this data into an array that can be used in a ForEach to produce sections. the simplest way to do this is to define a computed variable in your View with all of this together:

var groupData: [[MatchItem]] {
  let groups = Dictionary(grouping: todaysLlist, by: { $0.league_id })
  var returnData = [[MatchItem]]()
  for leagueID in groups.keys { // you may want to use groups.keys.sorted(), else the order is unpredictable
    returnData.append(groups[leagueID]!)
  }
  return returnData
}

now you can display the data in a View:

List {
  ForEach(groupData) { group in 
    Section(header: headerFor(group: group)) {
      ForEach(group) { matchItem in
        // display the view of matchItem
      }
    }
  }
}

the function to get the header for each group of MatchItems is simple: pick any on the MatchItems and read its league_id, because all of the MatchItems in the group have the same league_id. something like this:

func headerFor(group: [MatchItem]) -> some View {
  Text("league with id \(group[0].league_id)")
}

hope that gives you enough to work with,

DMG

  • (slight edits were made above about 15 minutes after the intial posting to correct some naming issues)

1      

Wow. This solves my problem. You are really appreciated. Thank you so much :D :)

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.