SF Symbolsをアニメーションさせる【UIKit / SwiftUI】
何の記事?
この記事ではSF Symbolsが提供しているアニメーション(Symbol Effect
)についてまとめました。
動作環境
- Xcode 16 Beta
- iOS 18.0 Beta
読んで欲しい人
- 最低限のUIKit/SwiftUIの知識がある人
- SF Symbolsが標準で提供する強力な
Symbol Effect
を使いこなしてより良いインターフェースを設計したい人
SF Symbolsについて
皆さんのアプリではSF Symbolsを利用していますか?
SF Symbolsは6,000以上のシンボルを収録したライブラリで、Appleプラットフォーム用のシステムフォントであるSan Franciscoとシームレスに統合できるように設計されています。SwiftUI/UIKitからも使いやすく設計され、ローカリゼーションやアニメーションなどを提供している強力なツールです。
WWDC19のIntroducing SF Symbolsで初めて発表され、毎年新機能が追加されています。
iOS17からのSF Symbols
iOS17ではSF Symbolsがアニメーション(Symbol Effect
)をサポートするようになりました。ユーザーの注意を引いたり、ユーザーの行動に対するフィードバック、状態の変化や進行中のアクティビティを表すのに役立ちます。
SwiftUI/UIKitそれぞれでアニメーションを設定する
// Symbol Effects in SwiftUI
Image(systemName: "mic")
.symbolEffect(.wiggle(.rotational.continuous())
// Symbol Effects in AppKit and UIKit
let imageView: UIImageView = ...
imageView.addSymbolEffect(.variableColor)
Discrete, Indefinite, Transition, Content Transition
Symbol Effectには4種類の振る舞いがあります。
アニメーションプリセットごとに1つ以上の振る舞いをサポートします。
例えばAppearアニメーションはIndefinite、Transitionに対応します。
.symbolEffect(.appear, value:)
の形で適用すると、Indefiniteの動作になります。これは周囲のレイアウトを変更しません。
// Indefinite
Image(systemName: "moon.stars")
.symbolEffect(.appear, isActive: isMoonHidden)
ビュー自体を追加/消失させ、周囲のレイアウトにも影響を与えるにはTransition版Appearを利用します。
.transition(.symbolEffect(.appear))
をつけてif文等で囲んでビュー自体を削除/追加することで、ビューが出現/消失する時にアニメーションされます。
// Transition
if !isMoonHidden {
Image(systemName: "moon.stars")
.transition(.symbolEffect(.appear))
}
Appearの2通りの使い方
Discrete
- 一回のみアニメーションする動き。
Indefinite
- Symbol Effectが削除されるまでアニメーションを保持する動き
Transition
- シンボルをビューの内外に移動させる遷移動作
Content Transition
- あるシンボルから別のシンボルへとアニメーション化する動作
アニメーションプリセット
SF Symbolsには標準でいくつかのアニメーションのプリセットが用意されています。
アニメーションは過度に使いすぎると逆効果になります。目的に応じて適したアニメーションを指定しましょう。
Appear / Disappear
レイヤーごとにアニメーションしながらシンボルが出現/消失するアニメーションです。
AppearとDisappear
Bounce
レイヤーごとに高速に伸縮する動きでユーザーの注意を引くアニメーションです。
シンボルとのインタラクションが成功したりアクションが行われたことをフィードバックするのに便利です。
Scale
シンボルのサイズを変えて、アクションが実行されたことをフィードバックしたり、選択状態やシンボルの重要性を強調し注意を引けます。
視線やカーソルを合わせたホバー状態で大きくして強調したり、アイコンを押している状態で小さくすることで押し込んでいる感を表現することができます。
BounceとScaleのどちらを選択するのが良いか悩んだら、以下の方針で決めると良いです。
- Bounce
- アクションが発生したことを表したい
- アクションを起こす必要性を表したい
- Scale
- アイテムが選択されたときのフォーカスやフィードバックを提供した
Pulse
アイコンをシンボル全体、またはレイヤーごとに透明度を変えつつ明滅させ、進行中のアクティビティを表したりアイコンの意味を強調します。
Variable color
二つの異なる表現方法で、シンボル状態が時間と共に変化することを伝えます。
- Cumulative(累積的)
- レイヤーが次々とハイライトされ、前の状態が残る
- Iterative(反復的)
- 一度に一つのレイヤーをハイライトする
Replace / Magic Replace
シンボルが別のシンボルと入れ替わるアニメーションです。
機能の移行を示すシンボルの状態の変化を伝えるために使用されます。
再生ボタンと一時停止ボタンを入れ替えたり、テキストの選択時はコピー/ペーストボタンに変化したり、可能なアクションを表示するために使います。
// Content transition symbol effects in SwiftUI
Button {
isPaused.toggle()
} label: {
Image(systemName: "pause.fill" : "play.fill")
.contentTransition(.symbolEffect(.replace.offUp))
}
// Content transition symbol effects in AppKit and UIKit
let imageView: UIImageView = ...
// change the image with a Replace effect
if let pauseImage = UIImage(systemName: "pause.fill") {
imageView.setSymbolImage(pauseImage, contentTransition: .replace.offUp)
}
Magic Replace
iOS18 からは一部の関連するシンボル同士で入れ替わる時に有効なMagic Replace
が追加されました。シンボル同士の入れ替わりがよりスムーズなアニメーションで実現できます。
Wiggle
特定の方向に振動し、バネのようにアニメーションします。
アイコンの意味を強調したり、見落とされる可能性のある変更や行動喚起を強調することができます。
例えば、アイコンに含まれる矢印の方向を強調したりすることができます。
振動する方向(上下左右や斜め、時計回りや反時計回り、またはAngleで自由に指定することができる)は、アイコンごとに異なるデフォルトの方向が設定されています。
例えば矢印や紙飛行機などのシンボルは、その意味を強調するため、矢印の向きや紙飛行機の先端方向がデフォルトの方向として設定されています。
Breathe
- 滑らかな拡大・縮小、透明度の変化で呼吸しているかのような印象を与えるアニメーションです。ステータスの変化を伝えたり、アクティビティが行われていることを示すのに役立ちます。
Rotate
- シンボル全体または一部を回転させて、インジケーターとして使用したり、現実世界のオブジェクトのような動きを再現したりします。
- 例えばタスクが進行中の時、アイコンを回転させることでタスクが進行中であることを表したりすることができます。
By LayerとWhole Symbol
SF Symbolsの各アイコンにはレイヤーが定義されています。
デフォルトでは各レイヤーごとにアニメーションされます。各レイヤーが1つずつアニメーションされます。(By Layer)
シンボル全体を一度に動かしたい場合はWhole Layerで動かします。
SF Symbols.app
SF Symbols 6 beta.appのスクリーンショット
全てのシンボルはApple DeveloperのサイトからダウンロードできるSF Symbols.appから確認することができます。
- ローカリゼーション
- Variable Color
- Symbol Effect
などを視覚的に確認することができます。
SF Symbols.appをダウンロードする
参考資料
HIG
Documentation
WWDC Sessions
Discussion