Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2026 Audio & VideoAccessibility & Inclusion

WWDC26 · 10 min · Audio & Video / Accessibility & Inclusion

Prepare your tvOS apps for Dynamic Type

Dynamic Type empowers people to comfortably read and interact with your app by letting them choose the text size that works best for them. You’ll learn how to get your app ready for Dynamic Type on tvOS through practical techniques for implementing font scaling and adapting your layouts for larger content. You’ll also discover how to optimize your media-focused interfaces like grids and carousels, ensuring a great experience for everyone who relies on different text sizes.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

Code shown on screen · 6 snippets

Adopt standard text styles swift · at 4:58 ↗
// Adopt standard text styles

VStack(spacing: 20) {
  Text("Signup information")
    .font(.caption.bold())
    .lineLimit(1)
    .foregroundStyle(.secondary)
    .frame(width: 300, alignment: .leading)
  HStack(alignment: .top, spacing: 40) { 
      //* ... *//
  }
}
Use flexible constraints swift · at 5:10 ↗
// Adopt standard text styles

VStack(spacing: 20) {
  Text("Signup information")
    .font(.caption.bold())
    .lineLimit(1)
    .foregroundStyle(.secondary)
    .frame(maxWidth: .infinity, alignment: .leading)
  HStack(alignment: .top, spacing: 40) { 
      /* ... */
  }
}
Dynamic Type with text styles in UIKit swift · at 5:55 ↗
// Hard coded text size in UIKit

titleLabel.font = UIFont.boldSystemFont(ofSize: 28)

// Dynamic Type with text styles in UIKit

titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
titleLabel.adjustsFontForContentSizeCategory = true
Adapt layout in response to dynamic type swift · at 7:09 ↗
// A view that shows a collection of movie posters

struct MovieShelf: View {
  @Environment(\.dynamicTypeSize) private var dynamicTypeSize
  var body: some View {
    ScrollView(.horizontal) {
      LazyHStack(spacing: 40) {
        ForEach(Asset.allCases) { asset in
          Button { 
            /* ... */
          } label: {
            asset.portraitImage
            Text(asset.title)
          }
          .containerRelativeFrame(
            .horizontal,
            count: dynamicTypeSize.isAccessibilitySize ? 4 : 6,
            spacing: 40)
        }
      }
    }
  }
}
Provide a conditional layout for when larger sizes are turned on swift · at 8:07 ↗
// A view that shows content in a card

struct CardContentView: View {
  @Environment(\.dynamicTypeSize) private var dynamicTypeSize
  var asset: Asset

  var body: some View {
    let layout = dynamicTypeSize.isAccessibilitySize ?
      AnyLayout(VStackLayout(alignment: .leading, spacing: 10)) :
      AnyLayout(HStackLayout(alignment: .top, spacing: 10))
    layout {
      /* ... */
    }
  }
}
UIKit adaptive layout that responds to content size changes swift · at 8:31 ↗
// UIKit adaptive layout that responds to content size changes

class AdaptiveLayoutViewController: UIViewController {
  let stackView = UIStackView()
  
  override func viewDidLoad() {
    super.viewDidLoad()
    updateLayout()

    let sizeTraits: [UITrait] = [UITraitPreferredContentSizeCategory.self]
    registerForTraitChanges(sizeTraits, action: #selector(updateLayout))
  }

  private func updateLayout() {
    if traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
      stackView.axis = .vertical
    } else {
      stackView.axis = .horizontal
    }
  }

}

Resources