Your First iOS & SwiftUI App: Polishing the App

Mar 1 2022 · Swift 5.5, iOS 15, Xcode 13

Part 4: A Second Screen

33. Challenge: Create a Leaderboard View

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 32. Introduction Next episode: 34. Create the Leaderboard View
Transcript: 33. Challenge: Create a Leaderboard View

As the first step to create our leaderboard view, we’ll start by creating a view for a single row inside the leaderboard. We’ll call this RowView.

We can implement RowView with 3 views inside an HStack, with a rounded rect in the background.

  • First, we’ll need a view for a number with a circle around it. We’ll call this RoundedTextView.
  • Second, we’ll need a text label for the score. We’ll call this ScoreText.
  • Third, we’ll need a text label for the date and time when the player earned the score. We’ll call this DateText.

Now, if you’re feeling REALLY confident about SwiftUI, you can try to pause the video and implement the entire thing on your own.

But if you’re still feeling like you could use a little help, keep watching and we’ll set up the scaffolding together. Then I’ll leave you with a challenge to fill in a few remaining pieces.

In Views, create a new SwiftUI View. Name it LeaderboardView.swift.

Start with:

struct LeaderboardView: View {
  var body: some View {
    RowView(index: 1, score: 10, date: Date())
  }
}

struct RowView: View {
  let index: Int
  let score: Int
  let date: Date

  var body: some View {
    HStack {
      Slider(value: .constant(50.0))
        .padding()
    }
  }
}

struct LeaderboardView_Previews: PreviewProvider {
  static var previews: some View {
    LeaderboardView()
    LeaderboardView()
      .previewLayout(.fixed(width: 568, height: 320))
    LeaderboardView()
      .preferredColorScheme(.dark)
    LeaderboardView()
      .previewLayout(.fixed(width: 568, height: 320))
      .preferredColorScheme(.dark)
  }
}

Create a new color LeaderboardRowColor. Cmd+Option+4 to open attributes inspector. Light color #D0E3F9, dark color ##303135.

Add to RowView:

.background(
  RoundedRectangle(cornerRadius: .infinity)
    .strokeBorder(Color("LeaderboardRowColor"), lineWidth: Constants.General.strokeWidth)
)
.padding(.leading)
.padding(.trailing)
.frame(maxWidth: 480.0)

Add to RoundedViews.swift:

struct RoundedTextView: View {
  let text: String

  var body: some View {
    Text(text)
  }
}

In same file, add to PreviewView, right before RoundRectTextView:

RoundedTextView(text: "1")

Add to TextViews.swift:

struct ScoreText: View {
  let score: Int

  var body: some View {
    Text(String(score))
  }
}

struct DateText: View {
  let date: Date

  var body: some View {
    Text(date, style: .time)
  }
}

Add to previews (above button):

ScoreText(score: 459)
DateText(date: Date())

Add to Constants.swift:

enum Leaderboard {
  public static let leaderboardScoreColWidth = CGFloat(50.0)
  public static let leaderboardDateColWidth = CGFloat(170.0)
  public static let leaderboardMaxRowWidth = CGFloat(480.0)
}

Replace hardcoded 480 with:

.frame(maxWidth: Constants.Leaderboard.leaderboardMaxRowWidth)

Your challenge will be to implement these three views, and then use them in your leaderboard RowView.

Here are a few hints:

  • RoundedTextView should be a lot like RoundedImageViewStroked, except it will be a Text view instead of an Image view.
  • ScoreText should apply kerning, foreground color, and font text attributes, based on Luke’s design.
  • DateText should apply the exact same styles as ScoreText, so once you have that one figured out, you can repeat them here.
  • Finally, when you add these views to your RowView, you should apply a frame view modifier to the ScoreText and DateText, setting their width to the values we set up together in the constants.

Pause the video and give it a shot. Good luck!

Copy/paste styles from RoundedImageViewStroked to RoundedTextView.

Apply these to ScoreText and DateText:

.kerning(-0.2)
.foregroundColor(Color("TextColor"))
.font(.title3)

In LeaderboardView.swift, replace slider with:

RoundedTextView(text: String(index))
Spacer()
ScoreText(score: score)
  .frame(width: Constants.Leaderboard.leaderboardScoreColWidth)
Spacer()
DateText(date: date)
  .frame(width: Constants.Leaderboard.leaderboardDateColWidth)