SF Symbols 2
Design 入门 22m

SF Symbols 2 全面解读

SF Symbols 2

2020年6月23日

在 Apple 官方观看视频

一句话判断

SF Symbols 2 新增了 750+ 个图标、颜色渲染模式和自定义权重——如果你还在用第三方图标库,是时候认真考虑全面切换到 SF Symbols 了。

这场 Session 讲了什么

SF Symbols 是 Apple 的系统图标库,随 Apple 平台内置,可以在所有 Apple 操作系统上免费使用。SF Symbols 2 带来了大量更新:图标数量从约 1500 个增加到 2250+ 个,覆盖了更多使用场景(智能家居、医疗健康、汽车等)。

最重要的新特性是颜色渲染模式(Rendering Modes)。以前 SF Symbols 只有单色(monochrome)模式——你设置什么颜色,整个图标就是什么颜色。SF Symbols 2 引入了三种新的渲染模式:hierarchical(层级模式,主色和辅色有深浅区分)、palette(调色板模式,可以独立设置不同部分的颜色)和 multicolor(多色模式,使用图标内置的语义颜色)。

Session 还介绍了 SF Symbols 的可定制性增强。开发者现在可以创建自定义的 SF Symbols,使用与系统图标相同的模板格式,并享受自动的颜色匹配、光学尺寸适配和本地化支持。这意味着你可以把公司的品牌图标也做成 SF Symbol 格式,与系统图标无缝混用。

值得深挖的点

Hierarchical 渲染模式的实用价值

Hierarchical 模式自动为图标的不同层级生成深浅不同的颜色。比如一个”文件夹”图标,文件夹主体用你指定的颜色,标签页部分自动使用更浅的同色系。这种自带的视觉层次感比手动设置两个颜色更协调。更重要的是,当系统切换到 Dark Mode 时,层级关系自动反转,不需要你手动调整。

Alignment Rect 与文本基线对齐

SF Symbols 2 的所有图标都包含了精确的 alignment rect 信息,确保与文本的基线对齐。这意味着 Image(systemName: "star.fill") + Text("收藏") 的组合中,图标和文字的垂直位置是精确对齐的,不需要手动调 offset。这个特性对 SwiftUI 来说是自动的,但在 UIKit 中需要使用 UIImagealignmentRectInsets 属性。

代码片段

import SwiftUI

// SF Symbols 2 的渲染模式
struct SymbolModesView: View {
    var body: some View {
        VStack(spacing: 24) {
            // 单色模式(默认)
            Image(systemName: "externaldrive.badge.wifi")
                .symbolRenderingMode(.monochrome)
                .font(.largeTitle)
                .foregroundColor(.blue)
            
            // 层级模式——自动生成深浅层次
            Image(systemName: "externaldrive.badge.wifi")
                .symbolRenderingMode(.hierarchical)
                .font(.largeTitle)
                .foregroundColor(.blue)
            
            // 调色板模式——自定义多色
            Image(systemName: "externaldrive.badge.wifi")
                .symbolRenderingMode(.palette)
                .foregroundStyle(.blue, .orange)  // 第一层蓝色,第二层橙色
                .font(.largeTitle)
            
            // 多色模式——使用图标内置的语义颜色
            Image(systemName: "externaldrive.badge.wifi")
                .symbolRenderingMode(.multicolor)
                .font(.largeTitle)
        }
    }
}
// SF Symbols 的权重与大小变体
struct SymbolVariantsView: View {
    var body: some View {
        VStack(spacing: 16) {
            // 不同字重对应的图标粗细
            HStack(spacing: 12) {
                Image(systemName: "star").fontWeight(.ultraLight)
                Image(systemName: "star").fontWeight(.light)
                Image(systemName: "star").fontWeight(.regular)
                Image(systemName: "star").fontWeight(.medium)
                Image(systemName: "star").fontWeight(.semibold)
                Image(systemName: "star").fontWeight(.bold)
                Image(systemName: "star").fontWeight(.heavy)
                Image(systemName: "star").fontWeight(.black)
            }
            .font(.title)
            
            // 图标变体:fill / slash / circle 等
            HStack(spacing: 16) {
                Image(systemName: "star")          // 线框
                Image(systemName: "star.fill")     // 填充
                Image(systemName: "star.slash")    // 删除线
                Image(systemName: "star.circle")   // 圆形背景
                Image(systemName: "star.square")   // 方形背景
            }
            .font(.title2)
            
            // 与文本自动基线对齐
            HStack(alignment: .firstTextBaseline) {
                Image(systemName: "checkmark.circle.fill")
                    .foregroundColor(.green)
                Text("已完成")
                    .font(.body)
            }
        }
    }
}
// SF Symbols 在按钮和标签中的使用
struct SymbolUsageView: View {
    @State private var isBookmarked = false
    
    var body: some View {
        VStack(spacing: 20) {
            // 动态切换图标的 fill 变体
            Button {
                isBookmarked.toggle()
            } label: {
                Label(
                    isBookmarked ? "已收藏" : "收藏",
                    systemImage: isBookmarked ? "bookmark.fill" : "bookmark"
                )
                .font(.headline)
                .foregroundColor(isBookmarked ? .yellow : .blue)
            }
            
            // 使用 SF Symbols 构建工具栏
            HStack(spacing: 20) {
                Label("首页", systemImage: "house")
                Label("搜索", systemImage: "magnifyingglass")
                Label("收藏", systemImage: "heart")
                Label("设置", systemImage: "gearshape")
            }
            .font(.body)
            
            // 在 List 行中用作 accessory
            List {
                Label("Wi-Fi", systemImage: "wifi")
                Label("蓝牙", systemImage: "bluetooth")
                Label("蜂窝网络", systemImage: "antenna.radiowaves.left.and.right")
            }
        }
    }
}

最佳实践

  • 优先使用 SF Symbols 而非第三方图标库——系统图标自动适配 Dark Mode、Dynamic Type 和本地化
  • 使用 hierarchical 渲染模式替代手动设置多色,自动适配主题变化
  • 图标切换状态时(如收藏/取消收藏)使用 .fill 变体,保持图标形状一致
  • 在 SwiftUI 中使用 Label 而非 Image + Text 的组合,自动处理图标和文字的对齐
  • 自定义图标使用 SF Symbols 的 template 格式(SVG),放入 Asset Catalog 中作为自定义 symbol

还有什么值得关注

  • SF Symbols 2 新增了大量 RTL(从右到左)语言自动镜像的图标,如箭头、返回按钮等
  • 在 Xcode 12 中,SF Symbols 应用可以直接预览不同渲染模式、大小和字重的效果
  • 自定义 SF Symbols 的制作工具已经集成到 SF Symbols app 中,可以导出为 SVG template
WWDC 2020