axiom-typography-ref
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTypography Reference
排版参考
Complete reference for typography on Apple platforms including San Francisco font system, text styles, Dynamic Type, tracking, leading, and internationalization through iOS 26.
这是一份完整的苹果平台排版参考指南,涵盖San Francisco字体系统、文本样式、Dynamic Type、字距调整(Tracking)、行高(Leading)以及国际化适配,支持至iOS 26版本。
San Francisco Font System
San Francisco字体系统
Font Families
字体家族
SF Pro and SF Pro Rounded (iOS, iPadOS, macOS, tvOS)
- Main system fonts for most UI elements
- Rounded variant for friendly, approachable interfaces (e.g., Reminders app)
SF Compact and SF Compact Rounded (watchOS, narrow columns)
- Optimized for constrained spaces and small sizes
- watchOS default system font
SF Mono (Code environments, monospaced text)
- Monospaced font for code editors and technical content
- Consistent character widths for alignment
New York (Serif system font)
- Serif alternative for editorial content
- Works with text styles just like SF Pro
SF Pro 和 SF Pro Rounded(适用于iOS、iPadOS、macOS、tvOS)
- 大多数UI元素的主要系统字体
- 圆角变体适用于友好、亲民的界面(如提醒事项App)
SF Compact 和 SF Compact Rounded(适用于watchOS、窄布局列)
- 针对受限空间和小尺寸优化
- watchOS默认系统字体
SF Mono(代码环境、等宽文本)
- 用于代码编辑器和技术内容的等宽字体
- 字符宽度一致,便于对齐
New York(衬线系统字体)
- 编辑类内容的衬线替代字体
- 与SF Pro一样支持文本样式
Variable Font Axes
可变字体轴
Weight Axis (9 weights)
字重轴(9种字重)
- Ultralight, Thin, Light, Regular, Medium, Semibold, Bold, Heavy, Black
- Continuous weight spectrum via variable fonts
- Avoid light weights at small sizes (legibility issues)
- Ultralight、Thin、Light、Regular、Medium、Semibold、Bold、Heavy、Black
- 通过可变字体实现连续的字重渐变
- 小尺寸下避免使用轻字重(易出现可读性问题)
Width Axis (WWDC 2022)
宽度轴(WWDC 2022推出)
- Condensed — narrowest width
- Compressed — narrow width
- Regular — standard width (default)
- Expanded — wide width
Access via:
swift
// iOS/macOS
let descriptor = UIFontDescriptor(fontAttributes: [
.family: "SF Pro",
kCTFontWidthTrait: 1.0 // 1.0 = Expanded
])SF Arabic (WWDC 2022)
- Matches SF Pro design language for Arabic text
- Proper right-to-left support
- Condensed — 最窄宽度
- Compressed — 窄宽度
- Regular — 标准宽度(默认)
- Expanded — 宽宽度
调用方式:
swift
// iOS/macOS
let descriptor = UIFontDescriptor(fontAttributes: [
.family: "SF Pro",
kCTFontWidthTrait: 1.0 // 1.0 = Expanded
])SF Arabic(WWDC 2022推出)
- 匹配SF Pro设计语言的阿拉伯语文本字体
- 原生支持从右到左排版
Optical Sizes
光学尺寸
Variable fonts automatically adjust optical size based on point size:
- Text variant (< 20pt) — more spacing, sturdier strokes
- Display variant (≥ 20pt) — tighter spacing, refined details
- Smooth transition (17-28pt) with variable SF Pro
From WWDC 2020:
"TextKit 2 abstracts away glyph handling to provide a consistent experience for international text."
可变字体可根据字号自动调整光学尺寸:
- 文本变体(<20pt)— 更大间距、更粗壮的笔画
- 展示变体(≥20pt)— 更紧凑的间距、更精细的细节
- 平滑过渡(17-28pt):可变SF Pro字体支持无缝切换
来自WWDC 2020的说明:
"TextKit 2 抽象了字形处理逻辑,为国际化文本提供一致的显示体验。"
Text Styles & Dynamic Type
文本样式与Dynamic Type
System Text Styles
系统文本样式
| Text Style | Default Size (iOS) | Use Case |
|---|---|---|
| 34pt | Primary page headings |
| 28pt | Secondary headings |
| 22pt | Tertiary headings |
| 20pt | Quaternary headings |
| 17pt (Semibold) | Emphasized body text |
| 17pt | Primary body text |
| 16pt | Secondary body text |
| 15pt | Tertiary body text |
| 13pt | Footnotes, captions |
| 12pt | Small annotations |
| 11pt | Smallest annotations |
| 文本样式 | iOS默认字号 | 使用场景 |
|---|---|---|
| 34pt | 页面主标题 |
| 28pt | 二级标题 |
| 22pt | 三级标题 |
| 20pt | 四级标题 |
| 17pt(Semibold) | 强调型正文文本 |
| 17pt | 主要正文文本 |
| 16pt | 次要正文文本 |
| 15pt | 三级正文文本 |
| 13pt | 脚注、说明文字 |
| 12pt | 小型注释文本 |
| 11pt | 最小尺寸注释文本 |
Emphasized Text Styles
强调型文本样式
Apply symbolic trait to get emphasized variants:
.boldswift
// UIKit
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title1)
let boldDescriptor = descriptor.withSymbolicTraits(.traitBold)!
let font = UIFont(descriptor: boldDescriptor, size: 0)
// SwiftUI
Text("Bold Title")
.font(.title.bold())Actual weights by text style:
- Some styles map to medium
- Others map to semibold, bold, or heavy
- Depends on semantic hierarchy
通过添加符号特性获取强调变体:
.boldswift
// UIKit
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title1)
let boldDescriptor = descriptor.withSymbolicTraits(.traitBold)!
let font = UIFont(descriptor: boldDescriptor, size: 0)
// SwiftUI
Text("Bold Title")
.font(.title.bold())各文本样式对应的实际字重:
- 部分样式映射为medium
- 其他样式映射为semibold、bold或heavy
- 具体取决于语义层级
Leading Variants
行高变体
Tight Leading (reduces line height by 2pt on iOS, 1pt on watchOS):
swift
// UIKit
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
let tightDescriptor = descriptor.withSymbolicTraits(.traitTightLeading)!
// SwiftUI
Text("Compact text")
.font(.body.leading(.tight))Loose Leading (increases line height by 2pt on iOS, 1pt on watchOS):
swift
// SwiftUI
Text("Spacious paragraph")
.font(.body.leading(.loose))紧凑行高(iOS下减少2pt行高,watchOS下减少1pt):
swift
// UIKit
let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
let tightDescriptor = descriptor.withSymbolicTraits(.traitTightLeading)!
// SwiftUI
Text("Compact text")
.font(.body.leading(.tight))宽松行高(iOS下增加2pt行高,watchOS下增加1pt):
swift
// SwiftUI
Text("Spacious paragraph")
.font(.body.leading(.loose))Dynamic Type
Dynamic Type
Automatic Scaling (iOS):
Text styles scale automatically based on user preferences from Settings → Display & Brightness → Text Size.
Custom Fonts with Dynamic Type:
swift
// UIKit - UIFontMetrics
let customFont = UIFont(name: "Avenir-Medium", size: 34)!
let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let scaledFont = bodyMetrics.scaledFont(for: customFont)
// Also scale constants
let spacing = bodyMetrics.scaledValue(for: 20.0)swift
// SwiftUI - .font(.custom(_:relativeTo:))
Text("Custom scaled text")
.font(.custom("Avenir-Medium", size: 34, relativeTo: .body))
// @ScaledMetric for values
@ScaledMetric(relativeTo: .body) var padding: CGFloat = 20自动缩放(iOS):
文本样式会根据用户在「设置→显示与亮度→文字大小」中的偏好自动缩放。
自定义字体适配Dynamic Type:
swift
// UIKit - UIFontMetrics
let customFont = UIFont(name: "Avenir-Medium", size: 34)!
let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let scaledFont = bodyMetrics.scaledFont(for: customFont)
// 同时缩放常量值
let spacing = bodyMetrics.scaledValue(for: 20.0)swift
// SwiftUI - .font(.custom(_:relativeTo:))
Text("Custom scaled text")
.font(.custom("Avenir-Medium", size: 34, relativeTo: .body))
// 使用@ScaledMetric处理数值
@ScaledMetric(relativeTo: .body) var padding: CGFloat = 20Platform Differences
平台差异
macOS
- No Dynamic Type support in AppKit
- Text style sizes optimized for macOS control sizes
- Catalyst apps use iOS sizes × 77% (legacy) or macOS-optimized sizes ("Optimize Interface for Mac")
watchOS
- Smaller text styles optimized for watch faces
- Tight leading default for compact displays
visionOS
- System fonts work identically to iOS
- Dynamic Type support included
macOS
- AppKit不支持Dynamic Type
- 文本样式字号针对macOS控件尺寸优化
- Catalyst应用默认使用iOS字号×77%(旧版)或macOS优化字号(需开启「Optimize Interface for Mac」)
watchOS
- 文本样式尺寸更小,专为表盘优化
- 默认使用紧凑行高以适配紧凑显示屏
visionOS
- 系统字体与iOS完全一致
- 支持Dynamic Type
Tracking & Leading
字距调整与行高
Tracking (Letter Spacing)
字距调整(Tracking)
Tracking adjusts space between letters. Essential for optical size behavior.
Size-Specific Tracking Tables:
SF Pro includes tracking values that vary by point size to maintain optimal spacing:
- Larger sizes: tighter tracking
- Smaller sizes: looser tracking
Example from Apple Design Resources:
- 34pt (largeTitle): +0.016 tracking
- 17pt (body): +0.008 tracking
- 11pt (caption2): +0.06 tracking
Tight Tracking API (for fitting text):
swift
// UIKit
textView.allowsDefaultTightening(for: .byTruncatingTail)
// SwiftUI
Text("Long text that needs to fit")
.lineLimit(1)
.minimumScaleFactor(0.5) // Allows tight trackingManual Tracking:
swift
// UIKit
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.preferredFont(forTextStyle: .body),
.kern: 2.0 // 2pt tracking
]
// SwiftUI
Text("Tracked text")
.tracking(2.0)
.kerning(2.0) // Alternative APIImportant: Use not API for semantic correctness. Tracking disables ligatures when necessary; kerning does not.
.tracking().kerning()字距调整用于调整字符间的间距,是实现光学尺寸特性的关键。
按字号区分的字距表:
SF Pro包含随字号变化的字距值,以保持最佳排版效果:
- 大字号:更紧凑的字距
- 小字号:更宽松的字距
来自苹果设计资源的示例:
- 34pt(largeTitle):+0.016字距
- 17pt(body):+0.008字距
- 11pt(caption2):+0.06字距
紧凑字距API(用于适配文本宽度):
swift
// UIKit
textView.allowsDefaultTightening(for: .byTruncatingTail)
// SwiftUI
Text("Long text that needs to fit")
.lineLimit(1)
.minimumScaleFactor(0.5) // 允许紧凑字距调整手动设置字距:
swift
// UIKit
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.preferredFont(forTextStyle: .body),
.kern: 2.0 // 2pt字距
]
// SwiftUI
Text("Tracked text")
.tracking(2.0)
.kerning(2.0) // 替代API重要提示: 为保证语义正确性,请使用而非API。字距调整(Tracking)会在必要时禁用连字,而字距微调(Kerning)不会。
.tracking().kerning()Leading (Line Spacing)
行高(Leading)
Default Line Height:
Calculated from font's built-in metrics (ascender + descender + line gap).
Language-Aware Adjustments:
iOS 17+ automatically increases line height for scripts with tall ascenders/descenders:
- Arabic
- Thai, Lao
- Hindi, Bengali, Telugu
From WWDC 2023:
"Automatic line height adjustment for scripts with variable heights"
Manual Leading:
swift
// UIKit
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 8.0 // 8pt additional space
// SwiftUI
Text("Custom spacing")
.lineSpacing(8.0)默认行高:
由字体内置的度量标准计算得出(上伸高度+下伸高度+行间距)。
多语言自适应调整:
iOS 17+会自动为包含高上伸/下伸笔画的脚本增加行高:
- 阿拉伯语
- 泰语、老挝语
- 印地语、孟加拉语、泰卢固语
来自WWDC 2023的说明:
"为具有可变高度的脚本自动调整行高"
手动设置行高:
swift
// UIKit
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 8.0 // 额外增加8pt行间距
// SwiftUI
Text("Custom spacing")
.lineSpacing(8.0)Third-Party Font Tracking
第三方字体字距支持
New in iOS 18:
Font vendors can embed tracking tables in custom fonts using STAT table + CTFont optical size attribute.
swift
let attributes: [String: Any] = [
kCTFontOpticalSizeAttribute as String: pointSize
]
let descriptor = CTFontDescriptorCreateWithAttributes(attributes as CFDictionary)
let font = CTFontCreateWithFontDescriptor(descriptor, pointSize, nil)iOS 18新增特性:
字体厂商可通过STAT表+CTFont光学尺寸属性,在自定义字体中嵌入字距表。
swift
let attributes: [String: Any] = [
kCTFontOpticalSizeAttribute as String: pointSize
]
let descriptor = CTFontDescriptorCreateWithAttributes(attributes as CFDictionary)
let font = CTFontCreateWithFontDescriptor(descriptor, pointSize, nil)SwiftUI AttributedString Typography
SwiftUI AttributedString排版
Font Environment Interaction
字体环境交互
Critical Pattern When using with SwiftUI's , paragraph styles (like ) can be lost if fonts come from the environment instead of the attributed content.
AttributedStringTextlineHeightMultipleFrom WWDC 2025-280:
"TextEditor substitutes the default value calculated from the environment for any AttributedStringKeys with a value of nil."
This same principle applies to —when your doesn't specify a font, SwiftUI applies the environment font, which can cause it to rebuild text runs and drop or normalize paragraph style details.
TextAttributedString关键注意事项:当在SwiftUI的中使用时,如果字体来自环境而非富文本内容本身,段落样式(如)可能会丢失。
TextAttributedStringlineHeightMultiple来自WWDC 2025-280的说明:
"对于值为nil的AttributedStringKeys,TextEditor会使用从环境计算出的默认值进行替换。"
这一规则同样适用于组件:当未指定字体时,SwiftUI会应用环境字体,这可能导致文本重新构建并丢失或标准化段落样式细节。
TextAttributedStringThe Problem
常见问题
swift
// ❌ WRONG - .font() modifier can override and drop paragraph styles
var s = AttributedString(longString)
// Set paragraph style
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
// ⚠️ No font set in AttributedString
Text(s)
.font(.body) // ⚠️ May rebuild runs, lose lineHeightMultipleWhy this fails:
- has no font attribute set (value is
AttributedString)nil - SwiftUI's modifier tells it "use this font for the whole run"
.font(.body) - SwiftUI rebuilds text runs with the environment font
- Paragraph styles get dropped or normalized during rebuild
swift
// ❌ 错误写法 - .font()修饰符会覆盖并丢失段落样式
var s = AttributedString(longString)
// 设置段落样式
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
// ⚠️ 未在AttributedString中设置字体
Text(s)
.font(.body) // ⚠️ 可能重新构建文本流,丢失lineHeightMultiple失败原因:
- 未设置字体属性(值为
AttributedString)nil - SwiftUI的修饰符指示「为整个文本流使用该字体」
.font(.body) - SwiftUI使用环境字体重新构建文本流
- 段落样式在重构过程中丢失或被标准化
The Solution
解决方案
Keep typography inside the AttributedString when you need fine control:
swift
// ✅ CORRECT - Font in AttributedString, no environment override
var s = AttributedString(longString)
// Set font INSIDE the attributed content
s.font = .system(.body) // ✅ Typography inside AttributedString
// Set paragraph style
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
Text(s) // ✅ No .font() modifierWhy this works:
- Font is part of the attributed content (not )
nil - No environment override from modifier
.font() - SwiftUI preserves both font AND paragraph styles
- Text runs remain intact with all attributes
当需要精细控制排版时,将字体设置在AttributedString内部:
swift
// ✅ 正确写法 - 字体在AttributedString中,不使用环境覆盖
var s = AttributedString(longString)
// 在富文本内容内部设置字体
s.font = .system(.body) // ✅ 排版属性包含在AttributedString中
// 设置段落样式
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
Text(s) // ✅ 不添加.font()修饰符成功原因:
- 字体是富文本内容的一部分(值不为)
nil - 没有使用修饰符覆盖环境
.font() - SwiftUI保留字体和段落样式
- 文本流保持完整,所有属性均被保留
When to Use Each Approach
两种方式的适用场景
Use Font in AttributedString (Fine Control)
在AttributedString中设置字体(精细控制)
swift
var s = AttributedString("Carefully styled text")
s.font = .system(.body)
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
p.alignment = .leading
s.paragraphStyle = p
Text(s) // No modifierWhen to use:
- Need precise paragraph styling (line height, alignment)
- Mixing multiple fonts in one string
- Content will be displayed in both and
TextTextEditor - Preserving exact formatting from rich text editor
swift
var s = AttributedString("Carefully styled text")
s.font = .system(.body)
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
p.alignment = .leading
s.paragraphStyle = p
Text(s) // 不添加修饰符适用场景:
- 需要精确的段落样式(行高、对齐方式)
- 在单个文本流中混合多种字体
- 内容需要同时在和
Text中显示TextEditor - 保留富文本编辑器的精确格式
Use .font() Modifier (Broad Override)
使用.font()修饰符(全局覆盖)
swift
Text("Simple text")
.font(.body)
.lineSpacing(4.0) // SwiftUI-level spacingWhen to use:
- Simple text without paragraph styles
- Want Dynamic Type automatic scaling
- Need SwiftUI's semantic font behavior (Dark Mode, accessibility)
- Intentionally overriding AttributedString fonts
swift
Text("Simple text")
.font(.body)
.lineSpacing(4.0) // SwiftUI层级的行间距适用场景:
- 无段落样式的简单文本
- 需要Dynamic Type自动缩放
- 依赖SwiftUI的语义字体行为(深色模式、无障碍适配)
- 有意覆盖AttributedString中的字体
Multiple Fonts in One String
单个文本流中使用多种字体
swift
var s = AttributedString("Title")
s.font = .system(.title).bold()
var body = AttributedString(" and body text")
body.font = .system(.body)
s.append(body)
Text(s) // ✅ No .font() modifier preserves both fontsswift
var s = AttributedString("Title")
s.font = .system(.title).bold()
var body = AttributedString(" and body text")
body.font = .system(.body)
s.append(body)
Text(s) // ✅ 不添加.font()修饰符可保留两种字体Common Mistake: Order Doesn't Matter
常见误区:设置顺序不影响结果
swift
// ❌ WRONG mental model: "Create AttributedString first"
var s = AttributedString(text)
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
s.font = .system(.body) // ⚠️ Setting font last doesn't help if you use .font() modifier
Text(s).font(.body) // Still breaks!The issue isn't when you set the font in . The issue is whether the attributed content carries its own font attributes versus relying on SwiftUI's environment.
AttributedString.font(...)swift
// ❌ 错误认知:「先创建AttributedString再设置属性」
var s = AttributedString(text)
var p = AttributedString.ParagraphStyle()
p.lineHeightMultiple = 0.92
s.paragraphStyle = p
s.font = .system(.body) // ⚠️ 即使最后设置字体,使用.font()修饰符仍会失效
Text(s).font(.body) // 仍然会丢失样式!问题的核心不在于何时在中设置字体,而在于富文本内容是否自带字体属性,还是依赖SwiftUI的环境。
AttributedString.font(...)Verification Checklist
验证清单
When using with paragraph styles:
AttributedString- Font set inside (not
AttributedString)nil - No modifier on
.font()view (unless intentionally overriding)Text - Paragraph styles set after or before font (order doesn't matter)
- Tested with actual content to verify line height/alignment preserved
当使用带段落样式的AttributedString时:
- 在内部设置字体(值不为
AttributedString)nil - 不在视图上添加
Text修饰符(除非有意覆盖).font() - 段落样式可在字体设置前后添加(顺序不影响)
- 使用实际内容测试,确保行高/对齐方式被正确保留
Internationalization
国际化适配
Bidirectional Text
双向文本
Complex Script Example (from WWDC 2021):
Kannada word "October":
- Character index 4 has split vowel → 2 glyphs
- Glyphs reorder before ligature application
- Glyph index ≠ character index
This is why TextKit 2 uses NSTextLocation instead of integer indices.
Hebrew/Arabic Selection:
Single visual selection = multiple NSRanges in AttributedString due to right-to-left layout.
复杂脚本示例(来自WWDC 2021):
卡纳达语中的「October」:
- 第4个字符包含拆分元音 → 对应2个字形
- 字形会在连字处理前重新排序
- 字形索引≠字符索引
这就是TextKit 2使用NSTextLocation而非整数索引的原因。
希伯来语/阿拉伯语文本选择:
单个视觉选择范围对应AttributedString中的多个NSRange,因为是从右到左排版。
Line Breaking
换行规则
Language-Aware (iOS 17+):
- Chinese, Japanese, Korean: break at semantic boundaries
- German: avoid breaking compound words
- English: prefer breaking at hyphens
Even Line Breaking (TextKit 2):
Justified paragraphs use improved line breaking algorithm:
- Reduces stretched-out lines
- More even interword spacing
- Automatic in TextKit 2
多语言自适应(iOS 17+):
- 中文、日文、韩文:在语义边界处换行
- 德语:避免拆分复合词
- 英语:优先在连字符处换行
均匀换行(TextKit 2):
对齐段落使用优化后的换行算法:
- 减少拉伸过长的行
- 使单词间距更均匀
- TextKit 2中默认启用
Text Clipping Prevention
文本截断预防
Best Practices:
- Use Dynamic Type (auto-adjusts)
- Set or
.lineLimit(nil)in SwiftUI.lineLimit(2...5) - Use for constrained single-line text
.minimumScaleFactor() - Test with large accessibility sizes
最佳实践:
- 使用Dynamic Type(自动调整)
- 在SwiftUI中设置或
.lineLimit(nil).lineLimit(2...5) - 对受限单行文本使用
.minimumScaleFactor() - 使用大尺寸无障碍模式测试
CSS & Web Typography
CSS与Web排版
System UI Font Families:
css
font-family: system-ui; /* SF Pro */
font-family: ui-rounded; /* SF Pro Rounded */
font-family: ui-serif; /* New York */
font-family: ui-monospace; /* SF Mono */Legacy:
css
font-family: -apple-system; /* deprecated, use system-ui */系统UI字体家族:
css
font-family: system-ui; /* SF Pro */
font-family: ui-rounded; /* SF Pro Rounded */
font-family: ui-serif; /* New York */
font-family: ui-monospace; /* SF Mono */旧版写法:
css
font-family: -apple-system; /* 已废弃,建议使用system-ui */Code Examples
代码示例
Emphasized Large Title (SwiftUI)
强调型大标题(SwiftUI)
swift
Text("Recipe Editor")
.font(.largeTitle.bold()) // Emphasized variantswift
Text("Recipe Editor")
.font(.largeTitle.bold()) // 强调变体Custom Font + Dynamic Type (UIKit)
自定义字体+Dynamic Type(UIKit)
swift
let customFont = UIFont(name: "Avenir-Medium", size: 17)!
let metrics = UIFontMetrics(forTextStyle: .body)
label.font = metrics.scaledFont(for: customFont)
label.adjustsFontForContentSizeCategory = trueswift
let customFont = UIFont(name: "Avenir-Medium", size: 17)!
let metrics = UIFontMetrics(forTextStyle: .body)
label.font = metrics.scaledFont(for: customFont)
label.adjustsFontForContentSizeCategory = trueRounded Design (UIKit)
圆角设计(UIKit)
swift
let descriptor = UIFontDescriptor
.preferredFontDescriptor(withTextStyle: .largeTitle)
.withDesign(.rounded)!
let font = UIFont(descriptor: descriptor, size: 0)swift
let descriptor = UIFontDescriptor
.preferredFontDescriptor(withTextStyle: .largeTitle)
.withDesign(.rounded)!
let font = UIFont(descriptor: descriptor, size: 0)Rounded Design (SwiftUI)
圆角设计(SwiftUI)
swift
Text("Today")
.font(.largeTitle.bold())
.fontDesign(.rounded)swift
Text("Today")
.font(.largeTitle.bold())
.fontDesign(.rounded)ScaledMetric (SwiftUI)
缩放度量(SwiftUI)
swift
struct RecipeView: View {
@ScaledMetric(relativeTo: .body) var padding: CGFloat = 20
var body: some View {
Text("Recipe")
.padding(padding) // Scales with Dynamic Type
}
}swift
struct RecipeView: View {
@ScaledMetric(relativeTo: .body) var padding: CGFloat = 20
var body: some View {
Text("Recipe")
.padding(padding) // 随Dynamic Type缩放
}
}Resources
参考资源
WWDC: 2020-10175, 2022-110381, 2023-10058
Docs: /uikit/uifontdescriptor, /uikit/uifontmetrics, /swiftui/font
WWDC视频:2020-10175、2022-110381、2023-10058
官方文档:/uikit/uifontdescriptor、/uikit/uifontmetrics、/swiftui/font