Leave a rating/review
Now that we have the data model in place, it’s time to hook it up to the leaderboard view.
Rather than just displaying a single hardcoded row, we will now display one row for each leaderboard entry.
To do this, we will make use of our old friend ForEach, which you may recall helped us create a bunch of Ring Views in the background.
We’ll also use a new SwiftUI View called ScrollView, which will make the view scrollable if there are more entries than can fit on one screen. Let’s try this out.
Add to LeaderboardView:
@Binding var game: Game
Update LeaderboardView_Previews:
struct LeaderboardView_Previews: PreviewProvider {
static private var leaderboardIsShowing = Binding.constant(true)
static private var game = Binding.constant(Game())
static var previews: some View {
LeaderboardView(leaderboardIsShowing: leaderboardIsShowing, game: game)
.environment(\.horizontalSizeClass, .compact)
LeaderboardView(leaderboardIsShowing: leaderboardIsShowing, game: game)
.previewLayout(.fixed(width: 568, height: 320))
LeaderboardView(leaderboardIsShowing: leaderboardIsShowing, game: game)
.preferredColorScheme(.dark)
.environment(\.horizontalSizeClass, .compact)
LeaderboardView(leaderboardIsShowing: leaderboardIsShowing, game: game)
.previewLayout(.fixed(width: 568, height: 320))
.preferredColorScheme(.dark)
}
}
And in BackgroundView:
LeaderboardView(leaderboardIsShowing: $leaderboardIsShowing, game: $game)
In LeaderboardView, replace RowView with:
VStack(spacing: 10) {
ForEach(game.leaderboardEntries.indices) { i in
let leaderboardEntry = game.leaderboardEntries[i]
RowView(index: i + 1, score: leaderboardEntry.points, date: leaderboardEntry.date)
}
}
We see no test data. To fix this, add to Game.swift:
init(loadTestData: Bool = false) {
if loadTestData {
leaderboardEntries.append(LeaderboardEntry(points: 100, date: Date()))
leaderboardEntries.append(LeaderboardEntry(points: 80, date: Date()))
leaderboardEntries.append(LeaderboardEntry(points: 60, date: Date()))
leaderboardEntries.append(LeaderboardEntry(points: 40, date: Date()))
leaderboardEntries.append(LeaderboardEntry(points: 20, date: Date()))
}
}
Update Leaderboard_Previews:
static private var game = Binding.constant(Game(loadTestData: true))
Wrap the VStack in a ScrollView:
ScrollView {
VStack(spacing: 10) {
ForEach(game.leaderboardEntries.indices) { i in
let leaderboardEntry = game.leaderboardEntries[i]
RowView(index: i + 1, score: leaderboardEntry.points, date: leaderboardEntry.date)
}
}
}
Build & run. Add a bunch of entries, and show it worknig.
Show how the X button now appears on top of the view, since not enough padding. To fix, add to bottom of HeaderView:
.padding(.top)