axiom-typography-ref

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Typography 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 ProSF Pro Rounded(适用于iOS、iPadOS、macOS、tvOS)
  • 大多数UI元素的主要系统字体
  • 圆角变体适用于友好、亲民的界面(如提醒事项App)
SF CompactSF 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 StyleDefault Size (iOS)Use Case
.largeTitle
34ptPrimary page headings
.title
28ptSecondary headings
.title2
22ptTertiary headings
.title3
20ptQuaternary headings
.headline
17pt (Semibold)Emphasized body text
.body
17ptPrimary body text
.callout
16ptSecondary body text
.subheadline
15ptTertiary body text
.footnote
13ptFootnotes, captions
.caption
12ptSmall annotations
.caption2
11ptSmallest annotations
文本样式iOS默认字号使用场景
.largeTitle
34pt页面主标题
.title
28pt二级标题
.title2
22pt三级标题
.title3
20pt四级标题
.headline
17pt(Semibold)强调型正文文本
.body
17pt主要正文文本
.callout
16pt次要正文文本
.subheadline
15pt三级正文文本
.footnote
13pt脚注、说明文字
.caption
12pt小型注释文本
.caption2
11pt最小尺寸注释文本

Emphasized Text Styles

强调型文本样式

Apply
.bold
symbolic trait to get emphasized variants:
swift
// 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
通过添加
.bold
符号特性获取强调变体:
swift
// 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
  • 其他样式映射为semiboldboldheavy
  • 具体取决于语义层级

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 = 20

Platform 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 tracking
Manual 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 API
Important: Use
.tracking()
not
.kerning()
API for semantic correctness. Tracking disables ligatures when necessary; kerning does not.
字距调整用于调整字符间的间距,是实现光学尺寸特性的关键。
按字号区分的字距表:
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
重要提示: 为保证语义正确性,请使用
.tracking()
而非
.kerning()
API。字距调整(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
AttributedString
with SwiftUI's
Text
, paragraph styles (like
lineHeightMultiple
) can be lost if fonts come from the environment instead of the attributed content.
From 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
Text
—when your
AttributedString
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.
关键注意事项:当在SwiftUI的
Text
中使用
AttributedString
时,如果字体来自环境而非富文本内容本身,段落样式(如
lineHeightMultiple
)可能会丢失。
来自WWDC 2025-280的说明:
"对于值为nil的AttributedStringKeys,TextEditor会使用从环境计算出的默认值进行替换。"
这一规则同样适用于
Text
组件:当
AttributedString
未指定字体时,SwiftUI会应用环境字体,这可能导致文本重新构建并丢失或标准化段落样式细节。

The 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 lineHeightMultiple
Why this fails:
  1. AttributedString
    has no font attribute set (value is
    nil
    )
  2. SwiftUI's
    .font(.body)
    modifier tells it "use this font for the whole run"
  3. SwiftUI rebuilds text runs with the environment font
  4. 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
失败原因:
  1. AttributedString
    未设置字体属性(值为
    nil
  2. SwiftUI的
    .font(.body)
    修饰符指示「为整个文本流使用该字体」
  3. SwiftUI使用环境字体重新构建文本流
  4. 段落样式在重构过程中丢失或被标准化

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() modifier
Why this works:
  1. Font is part of the attributed content (not
    nil
    )
  2. No environment override from
    .font()
    modifier
  3. SwiftUI preserves both font AND paragraph styles
  4. 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()修饰符
成功原因:
  1. 字体是富文本内容的一部分(值不为
    nil
  2. 没有使用
    .font()
    修饰符覆盖环境
  3. SwiftUI保留字体和段落样式
  4. 文本流保持完整,所有属性均被保留

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 modifier
When to use:
  • Need precise paragraph styling (line height, alignment)
  • Mixing multiple fonts in one string
  • Content will be displayed in both
    Text
    and
    TextEditor
  • 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 spacing
When 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 fonts
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) // ✅ 不添加.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
AttributedString
. The issue is whether the attributed content carries its own font attributes versus relying on SwiftUI's
.font(...)
environment.
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) // 仍然会丢失样式!
问题的核心不在于何时
AttributedString
中设置字体,而在于富文本内容是否自带字体属性,还是依赖SwiftUI的
.font(...)
环境。

Verification Checklist

验证清单

When using
AttributedString
with paragraph styles:
  • Font set inside
    AttributedString
    (not
    nil
    )
  • No
    .font()
    modifier on
    Text
    view (unless intentionally overriding)
  • 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:
  1. Use Dynamic Type (auto-adjusts)
  2. Set
    .lineLimit(nil)
    or
    .lineLimit(2...5)
    in SwiftUI
  3. Use
    .minimumScaleFactor()
    for constrained single-line text
  4. Test with large accessibility sizes
最佳实践:
  1. 使用Dynamic Type(自动调整)
  2. 在SwiftUI中设置
    .lineLimit(nil)
    .lineLimit(2...5)
  3. 对受限单行文本使用
    .minimumScaleFactor()
  4. 使用大尺寸无障碍模式测试

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 variant
swift
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 = true
swift
let customFont = UIFont(name: "Avenir-Medium", size: 17)!
let metrics = UIFontMetrics(forTextStyle: .body)
label.font = metrics.scaledFont(for: customFont)
label.adjustsFontForContentSizeCategory = true

Rounded 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