SF Symbols 3 for iOS: What’s New

Learn how to use the new features on SF Symbols 3, which allows you to customize colors, shading, accessibility and localization, as well as add custom symbols more easily. By Chuck Krutsinger .

5 (2) · 1 Review

Download materials
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Adding a Symbol to a Button

One good use of symbols is on buttons to help make their intended use more intuitive. You can use either the symbol by itself or combine it with text. Time to add a symbol to the Refresh button.

Open TubeStatusView.swift. Scroll down to navigationBarItems and find Text("Refresh"). Replace it with the following code:

//1
HStack(spacing: 10) {
  //2
  Image(systemName: "arrow.triangle.2.circlepath")
  Text("Refresh")
}

Here’s what this code does:

  1. Create a horizonal stack for the image you’re adding and the original text label.
  2. Use the SF Symbol name arrow.triangle.2.circlepath to fetch the symbol image.

Build and run. Now, the Refresh button has a refresh symbol on it. Nice!

TubeStatus with refresh symbol added to refresh button

Using Hierarchical Rendering

Now, you can put that new hierarchical shading option to use. Many of the Tube status symbols used in LineStatusRow have hierarchical rendering options. Why not use it for all status rows?

Open LineStatusRow.swift. In body, find status.uiImage() and place the following code below .padding(.trailing):

.symbolRenderingMode(.hierarchical)

This code simply invokes the hierarchical rendering mode.

Build and run. Scroll through the different Tube lines. Notice the shading applied to many of the symbols. Nice, huh? Symbols that don’t have hierarchical rendering simply ignore the modifier and continue to render as monochrome.

TubeStatus with symbols using hierarchical renderings

Using Palette Rendering

Now, it’s time to give palette rendering a try. Run the app and scroll to the bottom — you’ll see the label indicating when the data was last updated. Plain text is so boring! Time to spice it up with a colorful symbol.

Open TubeStatusView.swift. Inside ScrollView, replace Text("\(tubeStatus.lastUpdated)") as well as the .font(.footnote) and .padding() modifiers with the following:

//1
HStack {
  //2
  Image(systemName: "clock.badge.checkmark")
    .imageScale(.large)
    .padding()
    //3
    .symbolRenderingMode(.palette)
    //4
    .foregroundStyle(Color(uiColor: .systemGreen), Color(uiColor: .label))
  Text("\(tubeStatus.lastUpdated)")
    .font(.footnote)
    .padding()
}

Here’s what this code does:

  1. Define a horizontal stack to hold both the symbol and the text label.
  2. Load the clock.badge.checkmark image.
  3. Set the rendering mode to .palette so you can specify the colors to use.
  4. Use the .foregroundStyle() modifier to specify system colors to use for the two layers in the image.

In .foregroundStyle(), you can specify up to three colors. If you specify more colors than there are layers in the image, any unused colors are simply ignored. clock.badge.checkmark has two layers.

Build and run the app. Scroll to the bottom to see the new symbol.

TubeStatus with symbol added to footnote showing last update time

Understanding Symbol Variants

Symbol variants are another new feature of SF Symbols 3. Examples of variants are:

  • circle — example: play.circle
  • square — example: play.square
  • slash — example: play.slash
  • fill — example: play.fill
  • rectangle — example: play.rectangle

In many cases, the view that displays a symbol chooses a variant for you. For example, an iOS tab bar prefers the fill variant, and a navigation bar prefers the default variant. If you don’t specify the variant, the view may choose for you.

Open the SF Symbols 3 app and type play in the search bar. This displays all the symbol’s variants.

SF Symbols play symbol variants

Using Symbol Variants

You can use different variants to spice up the clock.badge.checkmark symbol you used with the Last updated footnote.

Go back to Xcode and open TubeStatusView.swift. Add the following code just below the .padding() modifier for the clock.badge.checkmark Image.

.symbolVariant(.fill)

Build and run. Scroll down to the footnote and notice how the clock part of the symbol is now filled in.

TubeStatus with filled symbol variant in footnote

Using Font Weights

Since SF Symbols is a font, you can use font stylings to alter their appearance. Next, you’ll add some font stylings to tweak the appearance of clock.badge.checkmark. The goal is to better match the footnote text.

Open TubeStatusView.swift. Add the following code just below the .padding() modifier for the clock.badge.checkmark.

.font(Font.title2.weight(.regular))

Build and run. Scroll down to the footnote and notice how the symbol is a little bit larger and heavier. Nice touch and so easy to do! For extra credit, feel free to try other font sizes and weights to see how the symbol renders.

TubeStatus with footnote symbol using larger font and regular weight

Customizing a Symbol

Adding your own custom symbols isn’t new in SF Symbols 3. However, new template formats make it much easier to add the full complement of symbol sizes, variants and localization capabilities.

Look at the status of the Picadilly stop, about midway down the list. exclamationmark.square represents No Step-Free Access — it’s not especially intuitive. You can do better! For example, a symbol showing someone walking on steps would better communicate that this stop requires using stairs.

Assets.xcassets has a custom.figure.steps symbol. This symbol is based on the figure.walk symbol. The process below shows how to create this symbol.

First, export the figure.walk symbol template using the SF Symbols 3 app. Choose File ▸ Export Template…, specifying the Variable Template Setup. This allows you to modify only three variants and let SF Symbols duplicate the rest. Name the file custom.figure.steps.

SF Symbols exporting custom.figure.steps template

Edit in Sketch or any drawing app of your choice. Be sure to use vectors to draw shapes so they’re scalable. The variable template only has three symbols to modify: Ultralight-S, Regular-S and Black-S. From those, SF Symbols 3 creates the other size and weight variations for you. What a time saver! Export your modified or custom symbol as an SVG from your drawing app.

Next, in the SF Symbols app, choose Custom Symbols in the left-side panel. Drag and drop the .svg file from Finder into the SF Symbols 3 app. Now, you can separate the symbol into layers for hierarchical or palette rendering. Use drag-and-drop to create a new layer. Assign primary and secondary colors to the layers you want to emphasize or de-emphasize. You can have up to four separate layers. custom.figure.steps has two.

SF Symbols import custom symbol and separate custom symbol layers

Once the symbol is the way you want it for your app, export it. Choose File ▸ Export Symbol…. Name the file custom.figure.steps and save it.

Finally, open Finder to show custom.figure.steps.svg and then drag and drop it into Assets.xcassets in Xcode. Make sure the asset name is custom.figure.steps.

Using a Custom Symbol

In Xcode, open TFLLineStatus.swift and find the noStepFreeAccess static variable. Replace image: Image(systemName: "exclamationmark.square")) with the following:

image: Image("custom.figure.steps"))

This code loads custom.figure.steps from Assets.xcassets. Since the image is in assets, you don’t specify the systemName argument label.

Build and run. Scroll down to the Picadilly stop and check out the new symbol. It’s much more helpful for those who need to avoid stairs.

TubeStatus with custom symbol for no step-free access status