Dynamic Type은 사용자의 시스템 설정에 따라 앱에서 글꼴 크기를 자동으로 변경하는 iOS 내장 기능입니다. 사용자는 설정 → 디스플레이 및 명도 → 텍스트 크기에서 선호하는 텍스트 크기를 설정하고, Dynamic Type을 지원하는 모든 앱이 추가 작업 없이 적응됩니다. Apple Human Interface Guidelines, 2024에 따르면, Dynamic Type 지원은 App Store에 출시하기 위한 필수 요구사항이며, iOS 플래폼의 접근성에서 기본 요소입니다.
중요 포인트
Dynamic Type은 iOS 7에서 도입된 iOS 기술로, 앱의 텍스트가 시스템 글꼴 크기 설정에 자동으로 적응할 수 있도록 합니다. 사용자는 모든 앱에서 동시에 글꼴을 크게 하거나 작게 할 수 있습니다 — 각 앱 내부에서 개별적으로 설정을 변경할 필요가 없습니다.
Apple WWDC 2023, “Make Your App Visually Accessible”에 따르면, iOS 사용자의 40% 이상이 기본 글꼴 크기를 변경합니다. 65세 이상 연령대의 경우 이 수치는 70%에 달합니다. Dynamic Type은 App Store 접근성 인증에 필수 요구사항입니다. 지원이 없으면 리뷰 도중 앱이 거부되는 이유가 됩니다.
작동 방식: 앱은 UIFont(name:size:)대신 UIFont.preferredFont(forTextStyle:)를 사용합니다. iOS는 현재 시스템 설정에 따라 스케일된 글꼴을 자동으로 반환합니다. 설정에서 크기가 변경되면 iOS가 UIContentSizeCategory.didChangeNotification을 생성합니다 — 앱은 레이아웃을 재계산해야 합니다.
Dynamic Type은 iOS 7에서 플랫 디자인과 함께 등장했습니다. iOS 10은 UIFontMetrics를 통한 커스텀 글꼴 지원을 추가했습니다. iOS 11은 접근성 단계(AccessibilityXXXL까지)를 도입했습니다. iOS 15는 SwiftUI에 Dynamic Type을 추가하고 자동 지원을 제공했습니다. 매 리리스마다 Apple은 요구사항을 강화하고 있으며, iOS 17부터는 Dynamic Type을 지원하지 않는 앱이 App Store Connect에 업로드될 때 경고를 받습니다.
iOS는 기본 설정에 대해 8가지 텍스트 스타일을 제공하며, 각각은 미리 정의된 크기와 구두끠가 있습니다:
| 스타일 | 상수 | 크기 (L) | 목적 |
|---|---|---|---|
| Large Title | .largeTitle | 34px | 화면 주 제목 |
| Title 1 | .title1 | 28px | 섹션 제목 |
| Title 2 | .title2 | 22px | 하위 제목 |
| Title 3 | .title3 | 20px | 카드 제목 |
| Headline | .headline | 17px (굵은 글씩) | 강조를 위한 굵은 글씩 |
| Body | .body | 17px | 주요 텍스트 |
| Callout | .callout | 16px | 보조 텍스트 |
| Caption 1 | .caption1 | 12px | 이미지 캡션 |
| Caption 2 | .caption2 | 11px | 작은 캡션 |
| Footnote | .footnote | 13px | 각주, 주석 |
올바른 스타일을 사용하는 것은 단순한 “외관”에 관한 것이 아닙니다. UIFont.TextStyle.body는 AccessibilityXXXL 모드에서 53px까지 도달할 수 있습니다. 앱이 body에 고정 17px 글꼴을 사용하는 경우, 글꼴 크기를 늘린 사용자에게 텍스트가 읽기 어려워집니다.
Dynamic Type은 단순히 스케일하지 않고 시각적 계층 구조를 보전합니다. Large Title은 헥상 Title 1보다 크고, Title 1은 Body보다 큽니다. 스케일링 계수는 다릅니다: 제목은 주요 텍스트보다 깥게 스케일되어 접근성 단계에서도 계층이 유지됩니다.
iOS는 텍스트 스케일링의 11단계를 지원하며, 두 카테고리로 나뒉니다:
body 스타일의 XS와 AccessibilityXXXL 사이의 차이는 14px에서 53px까지입니다 — 거의 4배입니다. 17px을 위해 설계된 레이아웃은 53px에서 완전히 깨집니다: 텍스트가 넘쳐 흑르고, 버튼이 검치며, 셀이 충돌합니다.
코드에서 현재 카테고리 확인:
let category = UIApplication.shared.preferredContentSizeCategory
// .extraSmall, .small, .medium, .large, .extraLarge ...
if category.isAccessibilityCategory {
// 대체 레이아웃 활성화
}
텍스트 크기 카테고리는 traitCollection.uiContentSizeCategory를 통해 사용할 수 있습니다. 시스템 설정이 변경되면 iOS가 모든 UIView에서 traitCollectionDidChange를 호출합니다. 이 메서드에서 글꼴을 업데이트하고 레이아웃을 재계산해야 합니다. SwiftUI는 이를 자동으로 수행하지만 UIKit은 수동 구독이 필요합니다.
UICollectionView에서는 UICollectionViewCompositionalLayout을 사용하세요 — 화면 너비와 텍스트 크기에 따라 열 수를 자동으로 조정합니다. 접근성 단계에서는 2열 레이아웃에서 1열 레이아웃으로 전환하여 텍스트가 잘리지 않고 요소가 검치지 않도록 합니다. 조건부 레이아웃을 사용하세요: 일반 너비에서는 2열, 압축된 경우나 접근성에서는 1열입니다.
UIKit에서 기본 구현 — UIFont.preferredFont(forTextStyle:). 이 메서드는 현재 시스템 설정에 따라 스케일된 글꼴을 반환합니다:
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
bodyLabel.font = UIFont.preferredFont(forTextStyle: .body)
커스텀 글꼴에는 UIFontMetrics를 사용하세요:
let customFont = UIFont(name: "Montserrat-Regular", size: 16)!
titleLabel.font = UIFontMetrics(forTextStyle: .body)
.scaledFont(for: customFont)
// 크기 변경 추적
NotificationCenter.default.addObserver(
self,
selector: #selector(preferredContentSizeChanged),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
Interface Builder에서 UILabel에 대해서는 글꼴을 텍스트 스타일로 설정하고 “Automatically Adjusts Font”를 율 크기만 하면 됩니다. 커스텀 글꼴의 경우 Interface Builder는 UIFontMetrics를 지원하지 않으므로 코드를 통해서만 가능합니다.
UIFontMetrics는 preferredFont와 동일한 스케일링 곡선을 사용합니다. fromTextStyle: .body, .headline 등을 지정할 수 있습니다. 각 스타일에는 고유한 스케일링 계수가 있습니다. Body는 중등하게 스케일하고, Large Title은 깥게 스케일합니다. 커스텀 글꼴을 주요 텍스트에 사용하는 경우 .body를 사용하세요.
SwiftUI에서 Dynamic Type 지원은 기본적으로 내장되어 있습니다. 모든 시스템 수정자(.font(.body), .font(.title))는 자동으로 스케일됩니다. 개발자가 UIFont.preferredFont를 호출할 필요가 없습니다.
예시:
Text("주요 텍스트")
.font(.body)
.lineLimit(nil)
.minimumScaleFactor(0.5)
커스텀 스케일에는 DynamicTypeSize를 사용하세요:
@Environment(\.dynamicTypeSize) var dynamicTypeSize
var body: some View {
Text("적응적 텍스트")
.font(.body)
.padding(dynamicTypeSize <= .large ? 8 : 16)
}
SwiftUI는 시스템 텍스트 크기가 변경될 때 뷰를 자동으로 업데이트합니다 — 추가 알림 구독이 필요하지 않습니다.
.font(.body) 수정자는 시스템 글꼴에서만 작동합니다. SwiftUI에서 커스텀 글꼴에 대해서는 UIFontMetrics를 내장 사용하는 Font.custom를 사용하세요. iOS 16부터 SwiftUI는 @Environment에서 DynamicTypeSize를 지원하여 여백과 레이아웃을 적응할 수 있습니다.
Auto Layout은 Dynamic Type 지원의 전제 조건입니다. 고정 너비와 높이(>=, <=)는 접근성 크기에서 깨집니다. UILabel에서는 intrinsicContentSize를 사용하세요 — 현재 글꼴 크기에 끔 높이를 자동으로 계산합니다.
적응적 레이아웃 규칙:
긴 텍스트(예: 기사, 이용약관)에는 UILabel에서 minimumScaleFactor를 설정하세요 — Auto Layout이 콘텐츠를 수용할 수 없을 때 최후의 수단으로 텍스트가 줄어들니다. 0.5의 값은 글꼴이 선호 크기의 50%까지 줄어들 수 있음을 뜻합니다.
크기 카테고리에 따라 여백을 조정하는 예:
let isAccessibility = traitCollection
.preferredContentSizeCategory.isAccessibilityCategory
stackView.spacing = isAccessibility ? 16 : 8
button.contentEdgeInsets = isAccessibility
? UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 24)
: UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
텍스트 잘리기 — numberOfLines = 1과 고정 너비의 UILabel은 AccessibilityXL에서 텍스트를 잘랍니다. 해결 방법: numberOfLines = 0 및 trailing 제약. 요소 검침 — 고정 높이의 버튼이 서로 검칭니다. 해결 방법: 자동 간격의 UIStackView. 화면 밖으로 나가는 콘텐츠 — 접근성 단계에서는 ScrollView가 필수입니다.
Xcode 시뮬레이터를 통해 텍스트 크기를 변경할 수 있습니다: 시뮬레이터 메뉴에서 Settings → Accessibility → Display & Text Size → Larger Text로 이동하세요. 11개의 모든 단계를 전환하면서 텍스트가 잘리지 않고, 버튼이 접근 가능하고, 레이아웃이 깨지지 않는지 확인하세요.
자동 테스트에는 XCUIApplication에서 contentSizeCategory 설정을 사용하세요:
func testAccessibilitySizes() {
let app = XCUIApplication()
app.launchArguments += [
"-UIPreferredContentSizeCategoryName",
"UICTContentSizeCategoryAccessibilityXXXL"
]
app.launch()
app.scrollViews.buttons["제출"].tap()
XCTAssertTrue(app.staticTexts["폼이 제출되었습니다"]
.waitForExistence(timeout: 5))
}
다양한 launchArguments를 사용한 XCUITest를 통해 CI에서 모든 스케일링 단계를 확인할 수 있습니다. 접근성 카테고리를 별도로 테스트하는 것을 잊지 마세요 — 이것들이 가장 자주 레이아웃을 깨튜립니다. Apple에 따르면 Dynamic Type 버그의 70%가 접근성 단계에서 발견되는데, 그 이유는 개발자가 표준 크기만 테스트하기 때문입니다.
Xcode Accessibility Inspector는 선택된 요소가 사용하는 글꼴(고정 또는 스케일 가능)을 보여줍니다. 요소가 시뮬레이터에서 텍스트 크기 변경에 반응하지 않는 경우 고정 글꼴이 사용되고 있는 것입니다. UIFont.preferredFont 또는 UIFontMetrics로 교체하세요.
자주 묻는 질문
시스템 크기 설정에 따라 앱에서 자동으로 텍스트 크기를 조절하는 것입니다. 사용자가 설정에서 크기를 변경하면 지원되는 모든 앱이 개발자 개입 없이 적응됩니다.
아닙니다. 커스텀 글꼴에는 UIFontMetrics(scaledFont:)를 사용하세요. 이 메서드는 지정된 텍스트 스타일에 상대적으로 임의 글꼴을 스케일하며 비율을 유지합니다.
11단계: 5개의 표준 (XS, S, M, L, XL)과 6개의 접근성 단계(AccessibilityXL부터 AccessibilityXXXXXL까지)입니다. body 글꼴 크기는 14px에서 53px까지 다양합니다.
UIKit에서는 UIContentSizeCategory.didChangeNotification을 통해 구독합니다. SwiftUI에서는 @Environment(\.dynamicTypeSize)를 사용하세요 — 시스템 설정이 변경되면 뷰가 자동으로 업데이트됩니다.
글꼴을 크게 설정한 사용자는 잘린 텍스트, 검침 된 요소 및 고장난 버튼을 보게 됩니다. 접근성 요구사항 위반으로 앱이 App Store 리뷰에서 거부될 수 있습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.