How to Use SF Symbols in SwiftUI With Image(systemName:)

A practical, step-by-step guide to adding, sizing, weighting, and coloring SF Symbols in SwiftUI using Image(systemName:), the most common way iOS developers display native icons.

What You Will Build

By the end of this guide you will be comfortable placing any SF Symbol into a SwiftUI view and controlling its size, weight, scale, and color.

These are the everyday operations you reach for constantly when building real screens. They cover tab bar icons, button glyphs, list row accessories, and status indicators.

You need a Mac with Xcode and the free SF Symbols app installed. The SF Symbols app is where you find and copy the exact symbol names you will paste into code.

Nothing here requires third-party packages. Everything ships with the SwiftUI framework.

Step 1: Find the Right Symbol Name

Open the SF Symbols app and use the search field to describe what you want, such as gear, trash, or star. The catalog is organized into categories on the left if you prefer to browse.

When you find a symbol, select it and copy its name. Names use lowercase words separated by dots, like `square.and.arrow.up` or `person.crop.circle`.

Many symbols have variants. A base name like `star` often has companions such as `star.fill`, `star.circle`, and `star.slash`, which you can see grouped in the app.

Verify the symbol's minimum OS availability in the app's inspector panel before committing to it. This avoids surprises on older deployment targets.

Step 2: Display the Symbol

In SwiftUI, render a symbol with the system image initializer.

Image(systemName: "star.fill")

That is the entire baseline. The symbol appears at a default size derived from the surrounding context, already matching the system font metrics.

If you place it next to text in an `HStack`, it aligns to the text baseline automatically. You can also embed a symbol directly inside a `Label`, which pairs an icon with a title in one component.

Label("Favorite", systemImage: "star.fill")

This Label form is preferred for buttons, list rows, and toolbar items because the system decides how to present the icon and text per context.

Step 3: Control Size With Font and imageScale

Because symbols behave like text glyphs, the cleanest way to size them is with the `font` modifier. A symbol respects text styles like `.title`, `.headline`, and `.body`.

Image(systemName: "star.fill")
    .font(.title)

Using a semantic text style is best for accessibility because the symbol scales with Dynamic Type when the user changes their text size.

For relative tuning, apply `imageScale`, which offers `.small`, `.medium`, and `.large`.

Image(systemName: "star.fill")
    .imageScale(.large)

Reach for a fixed point size with `.font(.system(size:))` only when you genuinely need a specific dimension, since hard-coded sizes do not adapt to the user's text settings.

Step 4: Set Weight to Match Surrounding Text

Symbol weight should usually mirror the weight of nearby text so the icon does not look too light or too heavy. You set weight through the font.

Image(systemName: "bolt.fill")
    .font(.body.weight(.semibold))

Weights range from ultralight through black, the same scale San Francisco uses. Picking a weight near your label's weight keeps the pairing visually balanced.

Weight and scale work together. You can combine a semibold weight with a large scale to make an icon read as prominent without changing its point size.

Experiment in the SF Symbols app first. It lets you preview every weight and scale combination before you write the code.

Step 5: Apply Color and Rendering Modes

The simplest coloring approach is `foregroundStyle`, which tints a monochrome symbol.

Image(systemName: "heart.fill")
    .foregroundStyle(.red)

For richer looks, choose a rendering mode with `symbolRenderingMode`. Hierarchical applies opacity-based depth from a single color.

Image(systemName: "speaker.wave.3.fill")
    .symbolRenderingMode(.hierarchical)
    .foregroundStyle(.blue)

Palette mode lets you pass multiple styles for symbols with distinct layers, and multicolor uses a symbol's own built-in colors.

Image(systemName: "cloud.sun.rain.fill")
    .symbolRenderingMode(.palette)
    .foregroundStyle(.gray, .yellow, .blue)

Not every symbol supports every mode meaningfully, so preview the symbol in the app to confirm it has the layers you expect.

Step 6: Use Variable Color for Status

Some symbols are designed to fill in stages, which suits signal strength, volume, or progress. You drive this with the variable value initializer.

Image(systemName: "wifi", variableValue: 0.6)

Pass a value between 0 and 1, and the symbol fills its variable layers proportionally. This gives you expressive status indicators without custom artwork.

This only works on symbols that include variable color layers. The SF Symbols app marks which symbols support variable color, so check there first.

Bind the value to your state, and the symbol updates as your data changes, which suits live download or connectivity meters.

Step 7: Add Motion With Symbol Effects

Modern SwiftUI can animate symbols through the `symbolEffect` modifier, giving you feedback without shipping motion assets.

Image(systemName: "bell.fill")
    .symbolEffect(.bounce, value: notificationCount)

Effects include bounce, pulse, scale, and others, and many can be triggered when a bound value changes. This is useful for confirming an action like adding to favorites.

These effects require sufficiently recent OS versions, so guard their use if you support older systems. The compiler and availability checks will guide you.

Keep motion purposeful. A subtle bounce on a meaningful event reads as polish, while constant animation reads as noise.

Common Pitfalls to Avoid

Do not hard-code point sizes everywhere. Favor semantic fonts so your icons scale with Dynamic Type and stay accessible.

Do not assume a symbol exists on every OS version. Always check availability in the app and provide a fallback for older targets.

Do not mismatch weight and scale with surrounding text. An icon that is much heavier or lighter than its label looks off, even if you cannot immediately say why.

Finally, remember that SF Symbols only solves iconography. Building, signing, and shipping the app still happens in Xcode and through the Apple Developer Program.

Pairing Symbols With Buttons and Toolbars

Symbols come into their own inside interactive controls. A `Button` can take a `Label`, and the system renders the icon appropriately for where the button lives.

Button {
    save()
} label: {
    Label("Save", systemImage: "square.and.arrow.down")
}

In a toolbar, the same `Label` may show as icon-only, while in a menu it shows icon and text together. You write the intent once and let the platform decide presentation.

This is why reaching for `Label` instead of a hand-built `HStack` pays off. You get context-appropriate rendering, correct spacing, and accessibility for free.

For a tab bar, attach the symbol through `tabItem` so each tab gets its standard icon-over-text layout without manual sizing.

Keeping Symbols Accessible

Symbols inherit a lot of accessibility behavior, but you still owe users a meaningful description when an icon stands alone. A bare icon button with no label is invisible to VoiceOver.

Add an accessibility label when the symbol carries meaning on its own.

Image(systemName: "trash")
    .accessibilityLabel("Delete")

When you use `Label` with visible text, the text already serves as the accessible description, so you usually do not need to add more.

Also prefer semantic fonts so symbols grow with Dynamic Type, and test with VoiceOver and the largest text sizes enabled. Accessible icons are part of shipping a polished iOS app, not an afterthought.

Frequently Asked Questions

What is the basic syntax to show an SF Symbol in SwiftUI?

Use Image(systemName: "name"), for example Image(systemName: "star.fill"). For icon-and-text pairs, use Label("Title", systemImage: "name").

How do I make an SF Symbol bigger?

Prefer a semantic font like .font(.title) so it scales with Dynamic Type, or use .imageScale(.large). Use .font(.system(size:)) only when you need a fixed size.

How do I color an SF Symbol?

Use .foregroundStyle for a single color, or set .symbolRenderingMode to hierarchical, palette, or multicolor for layered coloring.

Where do I find the exact symbol name?

Open the free SF Symbols app from Apple, search for the icon, and copy its name. The app also shows OS availability for each symbol.

Can SF Symbols animate?

Yes. On recent OS versions you can use the symbolEffect modifier for effects like bounce and pulse, often triggered by a changing value.