在 UIKit 和 AppKit 中使用 SF Symbols
SF Symbols in UIKit and AppKit
2021年6月10日
一句话判断
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.SymbolConfiguration 的 preferringMulticolor() 和可变值来控制图标的视觉状态。
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 简洁很多。