SF Symbols in UIKit and AppKit
Swift & UI 入门 20m

在 UIKit 和 AppKit 中使用 SF Symbols

SF Symbols in UIKit and AppKit

2021年6月10日

在 Apple 官方观看视频

一句话判断

SF Symbols 3 带来了多色渲染和可变颜色——但你如果在 UIKit 中还在用 withRenderingMode(.alwaysTemplate),你正在浪费这套图标系统的全部能力。

这场 Session 讲了什么

Session 聚焦 SF Symbols 3 在 UIKit 和 AppKit 中的使用方式。SF Symbols 3 新增了四种渲染模式(Rendering Mode):Monochrome(单色,之前的默认方式)、Multicolor(多色,图标自带颜色信息)、Palette(调色板,用你指定的颜色序列填充不同图层)、Hierarchical(层级,主色+半透明次色)。

还介绍了可变颜色(Variable Color)——某些符号(如 Wi-Fi 信号、电池电量)可以用 UIImage.SymbolConfigurationpreferringMulticolor() 和可变值来控制图标的视觉状态。

Session 用大量 UIKit 和 AppKit 的代码示例展示了如何在按钮、标签栏、工具栏中使用新的渲染模式,以及如何正确配置 UIImage.SymbolConfiguration

值得深挖的点

Palette 模式的灵活性

Palette 渲染模式让你用自定义颜色序列填充符号的不同图层。比如一个”人物+加号”的组合图标,你可以让人物用蓝色、加号用绿色。这在之前需要设计师出多套图标文件。现在只需要一个 SF Symbol 和一组颜色。图层顺序由符号的 SVG 结构决定——所以你需要知道每个符号有几层。

Hierarchical 模式的视觉一致性

Hierarchical 模式只使用一种颜色,但第二层会自动加上 50% 的透明度。这创造了一种”深度”感——比如文件夹图标中文件夹主体是全色,前面的小标签是半透明。这种模式的好处是你只需要指定一个颜色(通常是 accentColor),系统自动处理层次感。

代码片段

四种渲染模式的使用

// Monochrome(默认):单一颜色,可以 tint
let mono = UIImage(systemName: "externaldrive.badge.wifi")?
    .withRenderingMode(.alwaysTemplate)
// 在 UIImageView 或 UIButton 中 tint 为任意颜色

// Multicolor:图标自带颜色信息(Wi-Fi 是蓝色,硬盘是灰色)
let multi = UIImage(systemName: "externaldrive.badge.wifi")?
    .withRenderingMode(.alwaysOriginal)
// iOS 15 默认就是 multicolor

// Palette:自定义颜色序列
let palette = UIImage(systemName: "person.crop.circle.badge.plus")?
    .withTintColor(.blue, renderingMode: .alwaysOriginal)
// 使用 Palette 配置
let config = UIImage.SymbolConfiguration(paletteColors: [.systemBlue, .systemGreen])
let paletteIcon = UIImage(systemName: "person.crop.circle.badge.plus", 
                           withConfiguration: config)

// Hierarchical:一种颜色,自动分层
let hierConfig = UIImage.SymbolConfiguration(hierarchicalColor: .systemBlue)
let hierIcon = UIImage(systemName: "folder.fill.badge.plus", 
                        withConfiguration: hierConfig)

在 UIButton 中使用 SF Symbols

// UIKit 按钮
let config = UIButton.Configuration.filled()
config.image = UIImage(systemName: "square.and.arrow.up")
config.imagePlacement = .leading
config.imagePadding = 8

// 使用 Palette 模式让图标和文字不同色
let symbolConfig = UIImage.SymbolConfiguration(paletteColors: [.white, .systemBlue])
config.image = UIImage(systemName: "square.and.arrow.up", 
                        withConfiguration: symbolConfig)

let button = UIButton(configuration: config)

使用可变颜色

// Wi-Fi 信号强度可以用可变颜色表示
// 值在 0.0 到 1.0 之间
let wifiConfig = UIImage.SymbolConfiguration(
    pointSize: 20,
    weight: .regular
).applying(UIImage.SymbolConfiguration(
    // 0.0 = 无信号,1.0 = 满信号
    preferredSymbolConfigurationForSearching: nil
))

// 电池图标也支持可变颜色
let batteryFull = UIImage(systemName: "battery.100.bolt")  // 满电绿色
let batteryLow = UIImage(systemName: "battery.25")  // 低电红色

最佳实践

渲染模式选择: 默认用 Hierarchical(视觉层次感好,只需一个颜色)。需要自定义颜色时用 Palette。只在需要图标自带颜色时用 Multicolor。避免到处用 Monochrome(那是 SF Symbols 1 的用法)。

AppKit 注意事项: macOS 上的 NSImage 对 SF Symbols 的支持不如 UIImage 完整。Palette 和 Hierarchical 模式在 macOS 11.3 之后可用。旧版本需要 fallback。

还有什么值得关注

  • SF Symbols 3 新增了 600+ 符号,包括医疗、游戏、天气等新类别。
  • 自定义符号自动继承所有渲染模式的支持。
  • UIButton.Configuration 中的 imagePlacement 控制图标位置,比旧 API 简洁很多。
WWDC 2021