SF SymbolsをSwiftUIで使う方法について解説します。
環境
この記事で紹介する内容は、以下のバージョンでの動作を確認しています。
【iOS】17.0
【macOS】Ventura 13.6.1
SF Symbolsとは?
Appleが提供する5,000種類以上のシンボルを備えたアイコンセットです。Appleプラットフォームにおけるアプリケーションへの使用を目的にしており、システムフォントのSan Franciscoとシームレスに統合するようデザインされています。
次のサイトでダウンロードできるSF Symbolsアプリをインストールすると、使用可能なシンボルの一覧を検索できます。
本記事執筆時点はSF Symbols 5が最新版です。
システムシンボルの表示
SF Symbolsで用意されているシステムシンボルを表示するには、画像表示のImageビューを使用します。
1 2 3 |
Image(systemName: "システムシンボル名") |
systemName
システムシンボルの名称を指定します。
【使用例】
1 2 3 4 5 6 7 8 9 10 |
struct ContentView: View { var body: some View { Image(systemName: "hand.thumbsup.fill") .resizable() // 画像サイズをフレームに合わせる .scaledToFit() // 縦横比を維持しながらフレームに収める .frame(width: 150, height: 150) // フレームサイズの指定 } } |
Labelでの使用
【SwiftUI】 Labelの使い方で解説しているLabelビューでもSF Symbolsが使用できます。
1 2 3 |
Label("タイトル", systemImage: "システムシンボル名") |
【使用例】
1 2 3 4 5 6 7 8 |
struct ContentView: View { var body: some View { Label("Good!", systemImage: "hand.thumbsup.fill") .font(.system(size: 60)) } } |
システムシンボル名の取得
システムシンボル名は、SF Symbolsアプリで調べられます。対象シンボルを右クリックし「1個の名前をコピー」で名称がコピーできます。
他の選択として「1個のシンボルをコピー」を選択すると、フォントとしてコピーされますので、keynoteなどに文字としてシンボルを貼り付け可能です。
また、「1個のイメージをコピー」を選択すると、イメージデータとしてコピーされますので、Finderにペーストするとpngファイルができます。
サイズの指定方法
SF Symbolsは通常の画像イメージとして扱えますので、前の例で示したように、.resizable()と.frame()でサイズの指定ができます。画像のサイズ変更については、【SwiftUI】画像(Image)の使い方で詳しく解説しています。
さらに、テキストフォントとしても扱えますので、次のように.font()モディファイアでのサイズ指定も可能です。
1 2 3 4 5 6 7 |
.font(定義済フォントサイズ) または .font(.system(size: 数値)) |
.font()モディファイアの詳しい使い方は、【SwiftUI】フォントの指定方法(font)で解説しています。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
struct ContentView: View { var body: some View { VStack { HStack { Image(systemName: "cat.fill") .font(.body) Image(systemName: "cat.fill") .font(.title) Image(systemName: "cat.fill") .font(.largeTitle) } HStack { Image(systemName: "dog.fill") .font(.system(size: 20)) Image(systemName: "dog.fill") .font(.system(size: 40)) Image(systemName: "dog.fill") .font(.system(size: 60)) } } } } |
色の指定方法
SF Symbolsの色指定は一般的なViewと同様に、次の2つのModifierを使用します。
1 2 3 4 5 6 7 |
/// 前景色の指定 .foregroundStyle(ShapeStyle) /// 背景色の指定 .background(ShapeStyle) |
引数のShapeStyleには、Colorの他にグラデーションやImage等、ShapeStyleプロトコルに準拠したViewが指定できます。詳しい解説は【SwiftUI】色の指定方法(Color)を参照して下さい。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
struct ContentView: View { var body: some View { VStack { HStack { Image(systemName: "cat.fill") .font(.body) .foregroundStyle(.blue) Image(systemName: "cat.fill") .font(.title) .foregroundStyle(.green) Image(systemName: "cat.fill") .font(.largeTitle) .foregroundStyle(.pink) } HStack { Image(systemName: "dog.fill") .font(.system(size: 20)) Image(systemName: "dog.fill") .font(.system(size: 40)) Image(systemName: "dog.fill") .font(.system(size: 60)) } .foregroundStyle(LinearGradient(gradient: Gradient(colors: [.white, .black]), startPoint: .trailing, endPoint: .bottomLeading)) .background(.gray) } } } |
レンダリングモードの指定
シンボルの中には、いくつかのレンダリングモードをサポートするものがあります。
SF Symbolsアプリを使うと、次の手順で使用可能なレンダリングモードが確認できます。
- インスペクタ表示
- 情報インスペクタを選択
レンダリングモードを指定するには、次のモディファイアを使用します。
1 2 3 |
.symbolRenderingMode(レンダリングモード) |
以降では各レンダリングモードの違いと使用方法を解説します。
モノクロ(.monochrome)
シンボルを前景色で塗りつぶした単一レイヤーとしてレンダリングします。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
struct ContentView: View { var body: some View { ZStack { Color.mint.ignoresSafeArea() // 背景色指定 Image(systemName: "cloud.sun.rain.fill") .font(.system(size: 120)) .symbolRenderingMode(.monochrome) // モノクロレンダリングモード .foregroundStyle(.red) // 前景色指定 } } } |
階層(.hierarchical)
各レイヤーに異なる不透明度を適用します。前景色が指定可能です。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
struct ContentView: View { var body: some View { ZStack { Color.mint.ignoresSafeArea() // 背景色指定 Image(systemName: "cloud.sun.rain.fill") .font(.system(size: 120)) .symbolRenderingMode(.hierarchical) // 階層レンダリングモード .foregroundStyle(.red) // 前景色指定 } } } |
パレット(.palette)
各レイヤー毎に色を指定できます。
レイヤーの数はシンボルによって異なります
色の指定は、.forgroundStyle()モディファイアに2つまたは3つの引数を指定します。
1 2 3 4 5 6 7 |
/// 2つのレイヤーがある場合 .foregroundStyle(ShapeStyle1、ShapeStyle2) /// 3つのレイヤーがある場合 .foregroundStyle(ShapeStyle1、ShapeStyle2, ShapeStyle3) |
なお、レンダリングモードを明示的に指定せずに、複数階層の色指定をした場合もパレットレンダリングモードが適用されます。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
struct ContentView: View { var body: some View { ZStack { Color.mint.ignoresSafeArea() // 背景色指定 Image(systemName: "cloud.sun.rain.fill") .font(.system(size: 120)) .symbolRenderingMode(.palette) // パレットレンダリングモード .foregroundStyle(.orange, .blue, .pink) // パレット指定 } } } |
マルチカラー(.multicolor)
シンボル毎に定義されたオリジナルの配色で表示します。
.foregroundStyle()でメインカラーが変更可能なシンボルがあります。
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
struct ContentView: View { var body: some View { ZStack { Color.mint.ignoresSafeArea() // 背景色指定 VStack(spacing: 10) { SubView(symbolName: "cloud.sun.rain.fill") // メインカラーが変化しないシンボル SubView(symbolName: "filemenu.and.selection") // メインカラーが変化するシンボル SubView(symbolName: "folder.badge.plus") // メインカラーが変化するシンボル } } } struct SubView: View { var symbolName: String var body: some View { HStack { Image(systemName: symbolName) // メインカラー指定無し Image(systemName: symbolName).foregroundStyle(.blue) // メインカラー指定 Image(systemName: symbolName).foregroundStyle(.red) // メインカラー指定 } .symbolRenderingMode(.multicolor) // マルチカラーモード .font(.system(size: 80)) } } } |
変数値を持つシンボル
SF Symbolsには変数値を与えると表示が変化するものがあります。SF Symbolsアプリで「可変カラー」のカテゴリに属するシンボルで、下記のように電波の受信感度を表すようなアイコン等が含まれています。
これらの変数値を持つシンボルに、値を指定しながら表示するには、次のイニシャライザを使用します。
1 2 3 |
Image(systemName: "システムシンボル名", variableValue: 数値) |
variableValue
変数値を持つシンボルに対して、0.0から1.0の間の数値(Double型)を指定します。
シンボルが変数値をサポートしていない場合、このパラメーターは何の効果もありません。
【使用例】
スライダーで値を変えると、シンボルが変化していくサンプルコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
struct ContentView: View { @State private var waveSensitivity: Double = 0 var body: some View { Image(systemName: "dot.radiowaves.right", variableValue: waveSensitivity) .font(.system(size: 150)) VStack { Text("\(waveSensitivity)") // 数値表示 .font(.largeTitle) Slider(value: $waveSensitivity, in: 0...1.0) // スライダー表示 } .padding() } } |
シンボルの派生タイプ(Variant)指定
システムシンボルの中には、塗りつぶしバージョンや円に囲まれたものなど、いくつかの派生タイプを持つものがあります。
例えばハート型シンボルには下記のような派生タイプが存在します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
struct ContentView: View { var body: some View { VStack(alignment: .leading) { Label("Default", systemImage: "heart") Label("Fill", systemImage: "heart.fill") Label("Circle", systemImage: "heart.circle") Label("Square", systemImage: "heart.square") Label("Rectangle", systemImage: "heart.rectangle") Label("Slash", systemImage: "heart.slash") Label("Circle Fill", systemImage: "heart.circle.fill") Label("Square Fill", systemImage: "heart.square.fill") Label("Rectangle Fill", systemImage: "heart.rectangle.fill") Label("Slash Fill", systemImage: "heart.slash.fill") Label("Slash Circle", systemImage: "heart.slash.circle") Label("Slash Circle Fill", systemImage: "heart.slash.circle.fill") Spacer() } .font(.title) } } |
次のモディファイアを使うと、完全なシンボル名称を使わずとも、派生タイプのシンボル指定が可能です。
また、複数シンボルの派生タイプをまとめて追加もできます。
1 2 3 |
.symbolVariant(派生タイプ) |
派生タイプ(Variant)に使用できるパラメータは以下の通りで、モディファイアの重ね合わせ、または1回の呼び出しで複数の派生タイプをまとめて適用できます。
派生タイプ | 内容 |
---|---|
none | 無指定 |
circle | 円に囲まれたバージョン |
square | 正方形に囲まれたバージョン |
rectangle | 長方形に囲まれたバージョン |
fill | 塗りつぶされたバージョン |
slash | 斜め線の入ったバージョン |
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
struct ContentView: View { var body: some View { VStack { /// 無指定 MySymbols() .symbolVariant(.none) /// 塗りつぶし MySymbols() .symbolVariant(.fill) /// 円で囲む MySymbols() .symbolVariant(.circle) /// 円+斜め線(重ね合わせ適用) MySymbols() .symbolVariant(.slash) .symbolVariant(.circle) /// 塗りつぶし+円+斜め線(まとめて適用) MySymbols() .symbolVariant(.fill.slash.circle) Spacer() } .font(.largeTitle) } struct MySymbols: View { var body: some View { HStack { Image(systemName: "heart") Image(systemName: "person") Image(systemName: "magnifyingglass") } } } } |
重ね合わせや、まとめて指定する際の派生タイプの順番は、特に影響しません。
また、指定した派生タイプのシンボルが存在しない場合、指定は無視されます。
実行結果をみると、人物(person)には、斜め線+円のパターンがありません。また検索アイコンには斜め線のパターンが存在しないため、指定が無視されているのがわかります。
派生タイプ指定の解除について
派生タイプは積み重ねで設定されますので、既に何らかかの派生タイプが指定された後で、無指定のnoneを追加で指定しても設定済の派生タイプは解除できません。
この影響で不都合なケースがあります。
iOSではTabバーに塗りつぶしシンボルを使うのが推奨されていますが、これに従いTabバーに配置したシステムシンボルには、自動的に塗りつぶしの派生タイプ(.fill)が設定されるようになっています。
塗りつぶしではなく、どうしてもデフォルトのシンボルを使いたい場合は、次のモディファイア使用しましょう。既に設定されている派生タイプを解除できます。
1 2 3 |
.environment(\.symbolVariants, .none) |
【使用例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
struct ContentView: View { var body: some View { TabView { Text("Tab1") .tabItem{ Label("ライブラリ", systemImage: "photo.on.rectangle") .environment(\.symbolVariants, .none) } Text("Tab2") .tabItem{ Label("For You", systemImage: "heart.text.square") .environment(\.symbolVariants, .none) } Text("Tab3") .tabItem{ Label("アルバム", systemImage: "rectangle.stack") .environment(\.symbolVariants, .none) } Text("Tab4") .tabItem { Label("検索", systemImage: "magnifyingglass") // 検索アイコンは元々塗りつぶしタイプが存在しない } } } } |