史上最全的SF Symbols 使用指南

9,042 阅读9分钟

这是我参与更文挑战的第27天,活动详情查看: 更文挑战

本文翻译自:www.hackingwithswift.com/articles/23…

SF Symbols 在 WWDC 2019 期间推出。自此Apple 为我们提供了免费 Symbols,供我们在应用中使用,而且使用它们非常简单。 不久前,WWDC 2020 又引入了 SF Symbols 2.0,这让我们在 app 中使用精美的图标更加容易;而且 iOS 14 还增加了渲染多色图标的能力,iOS 15 还增加了对单个图层进行完全控制的能力。 在这篇文章中,我将指导您如何在您的项目中使用SF符号,并提供了 SwiftUI 和 UIKit 示例代码;

提示:浏览symbols 图标的最佳方式是使用官方免费提供的 SF Symbols app

截屏2021-06-28 下午9.19.12.png

如何加载SF Symbol

非常简单加载一个symbol, 直接写“star”就可以,但是如果你使用的是SF Symbol应用程序,你可以右键单击任何符号并选择复制名称。

在SwiftUI中,加载Image是通过将图像放置到视图层次结构中来完成的,使用的是systemName:

Image(systemName: "star")

在UIKit中,您需要使用UIImage,然后将其放置在UIImageView中,如下所示:

let image = UIImage(systemName: "star")

let imageView = UIImageView(image: image)

如何将SF Symbol插入到文本里

在SwiftUI中,将图像放在文本旁边是这样做的:

Label("Please try again", systemImage: "xmark.circle")

如果你想把它放在文本字符串中,最好用Image进行字符串插值,像这样:

Text("Please press the \(Image(systemName: "calendar")) button")

对于UIKit来说,代码稍微复杂一点,因为你需要使用NSAttributedStringNSTextAttachment 渲染成UILabel,但是同样的代码允许你将图像放置在你想要的任何地方:

let attachment = NSTextAttachment()
attachment.image = UIImage(systemName: "xmark.circle")

let imageString = NSMutableAttributedString(attachment: attachment)
let textString = NSAttributedString(string: "Please try again")
imageString.append(textString)

let label = UILabel()
label.attributedText = imageString
label.sizeToFit()

如何更改SF Symbol的大小

SF Symbol完全是矢量图形,因此您可以自由调整它们的大小而不会丢失质量。这也适用于内置的动态类型大小,其中SF Symbol将自行调整以匹配用户界面中的其他文本。

在SwiftUI中,调整SF Symbol的大小是使用内置文本样式的font()修饰符完成的,如下所示:

Image(systemName: "airplane")
    .font(.largeTitle)

或者使用像这样的自定义字体大小:

Image(systemName: "house")
    .font(.system(size: 72))

在UIKit中,调整符号的大小是使用UIImage.SymbolConfiguration,像这样:

let config = UIImage.SymbolConfiguration(textStyle: .largeTitle)
let image = UIImage(systemName: "airplane", withConfiguration: config)

或者使用像这样的自定义字体大小:

let config = UIImage.SymbolConfiguration(pointSize: 72)
let image = UIImage(systemName: "airplane", withConfiguration: config)

如何调整SF Symbol的比例

您刚刚看到了SF Symbol如何附加自定义字体大小,允许它们整齐地在文本中流动。然而,我们也可以对SF Symbol进行大小缩放,独立于它们的字体大小,这允许您对它们在用户界面中的外观进行更细粒度的控制。

在SwiftUI中,可以这样调整SF Symbol的比例:

Image(systemName: "house")
    .imageScale(.large)

正如我所说,这与任何自定义字体一起发生,所以如果你愿意,你可以同时使用这两种字体:

Image(systemName: "house")
    .font(.largeTitle)
    .imageScale(.large)

在UIKit中,这是通过另一种符号配置完成的,这次是使用scale构造器:

let config = UIImage.SymbolConfiguration(scale: .large)
let image = UIImage(systemName: "house", withConfiguration: config)

同样,您可以提供自定义字体和比例:

let config = UIImage.SymbolConfiguration(textStyle: .largeTitle, scale: .large)
let image = UIImage(systemName: "house", withConfiguration: config)

如何通过调整SF Symbol的权重使其加粗

所有SF Symbol都有各种字体重量,从超轻到黑色,这意味着你可以用很少的工作让它们脱颖而出。 在SwiftUI中,你可以这样调整SF Symbol的权重:

Image(systemName: "keyboard")
    .font(.largeTitle.weight(.black))

在UIKit中,通过创建UIImage的两个实例来调整权重。UIImage.SymbolConfiguration然后将它们组合在一起:

let largeTitle = UIImage.SymbolConfiguration(textStyle: .largeTitle)
let black = UIImage.SymbolConfiguration(weight: .black)
let combined = largeTitle.applying(black)
let image = UIImage(systemName: "keyboard", withConfiguration: combined)

如何更改SF Symbol的颜色

根据您使用的布局系统,SF Symbol以默认颜色呈现——SwiftUI使用默认字体颜色,而UIKit使用默认色调。无论哪种方式,您都可以通过多种方式自定义图标的颜色。

要使用SwiftUI完成SF Symbol的重新着色,即将其所有部分更改为一种颜色,请使用像这样的前景foregroundColor()修饰:

Image(systemName: "doc")
    .foregroundColor(.red)

在UIKit中,你有两个选择:要么改变你放置符号的图像视图的色调:

let image = UIImage(systemName: "doc")
let imageView = UIImageView(image: image)
imageView.tintColor = .systemRed

或者,调整UIImage本身,使其在任何地方都重新着色:

let image = UIImage(systemName: "doc")?.withTintColor(.systemRed, renderingMode: .alwaysOriginal)
let imageView = UIImageView(image: image)

如何渲染分层SF Symbol

在iOS15和更高版本中,许多SF Symbol图标包含几个代表图标深度的层,这些层可以用一点透明度来渲染,以帮助突出图标的含义。这即使在重新着色图像时也有效——由于透明度,你只会改变颜色的深浅。

在SwiftUI中,您可以呈现这样的分层SF Symbol:

Image(systemName: "square.stack.3d.down.right.fill")
    .symbolRenderingMode(.hierarchical)
    .foregroundColor(.indigo)

在UIKit中,这是通过指定层次颜色作为配置的一部分来完成的,如下所示:

let config = UIImage.SymbolConfiguration(hierarchicalColor: .systemIndigo)
let image = UIImage(systemName: "square.stack.3d.down.right.fill", withConfiguration: config)

如何渲染多色SF Symbol

在iOS14和以后的版本中,许多SF Symbol都有带有特定含义的内置颜色,例如“externaldrive.badge.plus”。徽章。外置驱动器使用默认颜色,但外置徽章是绿色的。默认情况下不启用这种多色绘图模式,所以你的符号将以上面讨论的颜色呈现,但是如果你愿意,你可以启用默认多色模式。

在SwiftUI中,您可以启用这样的多色SF Symbol:

Image(systemName: "externaldrive.badge.plus")
    .symbolRenderingMode(.multicolor)

在UIKit中,这是使用configurationPreferringMulticolor完成的,像这样:

let config =  UIImage.SymbolConfiguration.configurationPreferringMulticolor()
let image = UIImage(systemName: "externaldrive.badge.plus", withConfiguration: config)

**提示:**没有多色变体的图像将自动呈现单色,就像你没有改变设置一样。

如何创建自定义SF Symbol调色板

在iOS15之后,许多SF Symbol被分成支持两种甚至三种颜色的片段。它们的渲染方式取决于它们包含多少片段以及你提供了多少颜色:

  • 如果它们有1段,它将始终使用您指定的第一种颜色;其他颜色将被忽略。

  • 如果它们有2个段,并且您指定了1种颜色,这将用于两个段。如果您指定了2种颜色,每个段将使用一种。如果您指定了3种颜色,第三种将被忽略。

  • 如果它们有3个段,并且您指定了1种颜色,这将用于所有三个段。如果您指定了2种颜色,第一个段将使用一种颜色,其余两个段将使用另一种颜色。如果您指定了3种颜色,每个段将使用一种颜色。

在SwiftUI中,您可以使用. palette渲染模式渲染调色板图像,然后使用包含一种、两种或三种颜色的前景样式:

Image(systemName: "person.3.sequence.fill")
    .symbolRenderingMode(.palette)
    .foregroundStyle(.red, .green, .blue)

你实际上可以使用任何一种形状,不仅仅是颜色,这意味着你可以使用三种不同的材料:

Image(systemName: "person.3.sequence.fill")
    .symbolRenderingMode(.palette)
    .foregroundStyle(
        .ultraThickMaterial,
        .regularMaterial,
        .ultraThinMaterial
    )

甚至三个线性梯度:

Image(systemName: "person.3.sequence.fill")
    .symbolRenderingMode(.palette)
    .foregroundStyle(
        .linearGradient(colors: [.red, .black], startPoint: .top, endPoint: .bottomTrailing),
        .linearGradient(colors: [.green, .black], startPoint: .top, endPoint: .bottomTrailing),
        .linearGradient(colors: [.blue, .black], startPoint: .top, endPoint: .bottomTrailing)
    )
    .font(.largeTitle)

在UIKit中,这是使用另一个符号配置完成的,这次将颜色数组传递给paletteColors初始化构造器:

let config = UIImage.SymbolConfiguration(paletteColors: [.systemRed, .systemGreen, .systemBlue])
let image = UIImage(systemName: "person.3.sequence.fill", withConfiguration: config)

UIKit不能在其调色板中使用材料或渐变,只能使用颜色。

如何调整SF Symbol变体

在iOS15和更高版本中,一些SF Symbol提供了各种变体,即一个或多个圆形、填充、矩形、斜线或正方形。在UIKit中,您需要按名称激活这些符号——例如“bell. slash”——但是在SwiftUI中有一个symbolVariant()修饰符,使这变得更容易。

例如,这会呈现一个带有斜杠的铃铛图标:

Image(systemName: "bell")
    .symbolVariant(.slash)

这把钟周围有一个正方形:

Image(systemName: "bell")
    .symbolVariant(.square)

如果你需要,这些可以组合在一起,像这样:

Image(systemName: "bell")
    .symbolVariant(.fill.slash)
还有一个呈现原始图像的如果你需要在图标的两种状态之间移动,这很有帮助例如,这将在两种状态之间切换
struct ContentView: View {
    @State private var showingAlerts = true
    var body: some View {
        Toggle(isOn: $showingAlerts) {
            Label("Show Alerts", systemImage: "bell")
                .symbolVariant(showingAlerts ? .none : .slash)
        }
        .toggleStyle(.button)

    }

}

如何描述画外音的SF Symbol

默认情况下,许多SF Symbol都有有用的Voiceover标签,例如“heart”被读作“love”,“calendar.badge.plus”被读作“add to calendar”然而,许多其他图标没有这样的内置名称,包括复杂的图标,如“arrowshape.turn.up.backward.circle”。在这种情况下,您应该设置一个自定义的可访问性标签,描述VoiceVER的内容。

在SwiftUI中,您可以将自定义辅助功能标签附加到SF Symbol,如下所示:

Image(systemName: "arrowshape.turn.up.backward.circle")
    .accessibilityLabel("Go back")

如果您正在使用标签,Voiceover将使用标签的文本,即使它目前没有显示。

**提示:**您也可以使用与SF Symbol相同的名称将您的可访问性标签放入您的Localizable.字符串文件中,SwiftUI将使用它。

在UIKit中,可访问性标签设置在显示符号的控件上,如下所示:

let image = UIImage(systemName: "arrowshape.turn.up.backward.circle")
let imageView = UIImageView(image: image)
imageView.accessibilityLabel = "Go back"

如何使SF Symbol适应它们的上下文

在iOS15和以后,许多SF Symbol会自动适应它们的使用方式,包括“signature”符号的变化方式,以匹配各种本地化,如日语或希伯来语。

然而,SwiftUI有一个UIKit缺乏的强大功能,那就是根据上下文呈现SF Symbol的能力。这在TabView中,symbol的正确变体依赖于系统:iOS苹果的人机界面指南推荐填充图标,而在macOS中,他们推荐使用笔画。

SwiftUI在这里做了一些聪明的事情:如果你为标签项目使用SF Symbol,你不应该指定它是否被填充——它会根据系统自动适应。

因此,这将创建一个标签项,使用iOS上的填充人员符号,但在macOS上使用笔划的人员:

TabView {
    Text("Your View Here")
        .tabItem {
            Label("Home", systemImage: "person")
                .symbolVariant(.none)
        }
}

参考

www.hackingwithswift.com/articles/23…