NEW BOOK! SwiftUI Fundamentals: The essential guide to SwiftUI core concepts and APIs. Learn more ...NEW BOOK! SwiftUI Fundamentals:Master SwiftUI core concepts and APIs. Learn more...

Adapting images and symbols to Dynamic Type sizes in SwiftUI

Dynamic Type allows users to adjust text size across the system, improving readability and accessibility. When we use built-in fonts in SwiftUI, text scales automatically to match the user’s preferred size. However, text is only part of the interface. Other elements, such as images and symbols, also need to adapt to maintain a balanced layout.

In this post, we'll look at how to handle images in a Dynamic Type environment, covering both SF Symbols and custom images. We'll explore techniques to ensure meaningful icons remain clear at larger text sizes, scale custom images appropriately, and exclude decorative images when necessary to optimize space.

# Using SF Symbols with Dynamic Type

If we use icons to communicate important information, they need to stay clear and legible at larger font sizes. SF Symbols make this easy by scaling automatically with Dynamic Type, ensuring they adjust as text size changes.

These symbols integrate with the San Francisco system font, aligning naturally with different weights and sizes. They work well for conveying concepts or representing objects, especially alongside text.

Even though SF Symbols are placed inside an Image view, they behave more like text. They inherit font attributes from the environment to match surrounding content.

VStack {
    Image(systemName: "cloud.sun")
    Text("Partly Cloudy")
}
.font(.title)
Comparison of a weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing how both elements scale proportionally Comparison of a weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing how both elements scale proportionally

An important detail to keep in mind is that it's generally not recommended to use the resizable() modifier with SF Symbols. Applying resizable() to a symbol causes it to lose its symbol properties, meaning it will be treated more like a regular image. This prevents it from scaling automatically with Dynamic Type.

VStack {
    Image(systemName: "cloud.sun")
        .resizable()
        .scaledToFit()
        .frame(height: 28)
    Text("Partly Cloudy")
}
.font(.title)
Comparison of a weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing that the text scales up while the icon remains the same size Comparison of a weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing that the text scales up while the icon remains the same size

There may be cases where converting a symbol into an image and manually scaling it, as we would with custom images, is appropriate. However, in most situations, it's best to use SF Symbols as intended to ensure they remain consistent with surrounding text and provide the best user experience.

# Scaling custom images

Custom images from an asset catalog don't automatically resize with text. If an image is not purely decorative but conveys meaning, we should manually ensure it scales appropriately when the user adjusts their preferred font size.

SwiftUI provides the ScaledMetric API to make this easier to handle. Instead of defining multiple sizes for an image, we can specify a base value and store it in a property annotated with the @ScaledMetric property wrapper. By default, ScaledMetric adjusts relative to the body text style, but we can customize it to match a different text style.

In the example below, the image height will scale relative to the title font size.

struct ContentView: View {
    @ScaledMetric(relativeTo: .title)
    private var imageHeight = 28
    
    var body: some View {
        VStack {
            Image(.partlyCloudy)
                .resizable()
                .scaledToFit()
                .frame(height: imageHeight)
            Text("Partly Cloudy")
        }
        .font(.title)
    }
}
Comparison of a custom weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing that both the image and text scale proportionally Comparison of a custom weather icon and text at Large (Default) and XXX Large Dynamic Type sizes, showing that both the image and text scale proportionally

When designing with scaled metrics, it's important to start with a size that works well for the default Dynamic Type setting and ensure that images have a high enough resolution to scale up without losing quality.

# Handling decorative images

Decorative images that don't convey important meaning shouldn't be scaled, as they can take up valuable screen space that could be used for more important content. In some cases, it may even be best to remove decorative images altogether at larger text sizes.

We can determine the current Dynamic Type size by reading the dynamicTypeSize environment value. In the example below, the image remains visible for standard text sizes but is removed entirely when an accessibility text size is enabled, ensuring that text has as much space as possible.

struct ContentView: View {
    @Environment(\.dynamicTypeSize)
    private var typeSize
    
    var body: some View {
        VStack {
            if !typeSize.isAccessibilitySize {
                Image(decorative: "forecast")
            }
            Text("Weather Forecast")
        }
        .font(.title)
    }
}
Weather icon visible at Large text size and removed at Accessibility 1 Weather icon visible at Large text size and removed at Accessibility 1

Adapting images and symbols to Dynamic Type ensures that interfaces remain clear, accessible, and visually balanced across different text sizes. By making thoughtful adjustments to how images scale, or whether they appear at all, we can create layouts that adapt seamlessly to user preferences while maintaining clarity and usability.


If you want to build a strong foundation in SwiftUI, my new book SwiftUI Fundamentals takes a deep dive into the framework’s core principles and APIs to help you understand how it works under the hood and how to use it effectively in your projects.

For more resources on Swift and SwiftUI, check out my other books and book bundles.

SwiftUI Fundamentals by Natalia Panferova book coverSwiftUI Fundamentals by Natalia Panferova book cover

Deepen your understanding of SwiftUI!$35

The essential guide to SwiftUI core concepts and APIs

SwiftUI Fundamentalsby Natalia Panferova

  • Explore the key APIs and design patterns that form the foundation of SwiftUI
  • Develop a deep, practical understanding of how SwiftUI works under the hood
  • Learn from a former Apple engineer who worked on widely used SwiftUI APIs

Deepen your understanding of SwiftUI!

The essential guide to SwiftUI core concepts and APIs

SwiftUI Fundamentals by Natalia Panferova book coverSwiftUI Fundamentals by Natalia Panferova book cover

SwiftUI Fundamentals

by Natalia Panferova

$35