Search code examples
design-patternsswiftuifontsapp-storerating

SwiftUI - App Store Rating Section, Design Clone


I'm trying to orient a section in my app on the App Store design and build it in the same way:

enter image description here

Does anyone of you know if the code snippet is available somewhere? I only found animation challenges from the App Store.

Anyways, I tried to copy it by my own but I do not understand how the rounded Number (4,7) is getting created. Is it a custom font or is there some sort of layer around a standard font? At the moment I'm stuck cloning this layout.

Here's what I tried:

struct AppStoreRatingSection: View {
    var body: some View {
        HStack{
            VStack{
                Text("Bewertungen")
                    .font(.title)
                    .fontWeight(.heavy)
                    .foregroundColor(.primary)
                Text("4,3")
                    .font(.title)
                    .fontWeight(.heavy)
                    .foregroundColor(.primary)
            }
            Spacer()
            VStack {
                Text("Chart here")
            }
        }
        .padding(.horizontal)
    }
}

Many Thanks!


Solution

  • The rounded font variation of San Francisco is built into the operating system in the same way that the main font is (there are also serif and monospaced variants available).

    To access it, you need a slightly different variation to the argument you use within the .font() modifier:

    Text("4,7")
      .font(.system(.title, design: .rounded))
    

    For more information, see the documentation for the SwiftUI Font object.

    Also, note that the text you're actually displaying is most likely a formatted number rather than a string. If you let the system convert your numbers for you, it'll be locale-aware -- so where you see 4,7 I, here in the UK, would see 4.7 and so on.

    There are several ways to implement formatting, but using iOS 15's newest approach, it might look something like:

    struct MyView: View {
      var rating = 4.6542 // assume this is calculated somewow
    
      var body: some View {
        // ...
        Text(rating, format: .number.precision(.fractionLength(1)))
          .font(.system(.title, design: .rounded))
          // etc.
      }
    }