ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
アプリでシンボルをアニメーションする
アニメーションするシンボルでアプリを楽しくしましょう。シンボルエフェクトを作成し、統一された API を特徴とする、新しいSymbolsフレームワークを探索しましょう。SwiftUI、AppKit、UIKitにおいて、ユーザーインターフェイスでシンボルを簡単にアニメーションさせる方法、また、他のアプリのコンテンツと一緒に新しいアニメーションをシームレスに統合するためのヒントやトリックを学びます。このセッションを最大限に活用するには、まず"SF Symbols 5の新機能"をご覧になることをお勧めします。
リソース
関連ビデオ
WWDC23
-
ダウンロード
「アプリでシンボルをアニメーション化 する」へようこそ Anantと申します UIKitのエンジニアです SF SymbolsはApple インターフェイスの象徴的な部分
メニューやツールバーにサイドバー などで良い見栄えにできます またシンボルに慣れている人が 多いため アプリをより直感的に 使用できるようになります iOS 17とmacOS Sonomaでは シンボルをアニメーションで強化 アプリにこれまで以上の 活気をもたらします まずは「シンボルエフェクト」という 新しいシンボルの紹介 続いてSwiftUIの 新しいAPIについて またUIKitとAppKitによる アプリへのシンボル効果を交えて 説明します 最後にシンボル効果を有効活用するための ヒントをいくつか紹介します
では始めることにしましょう
iOS 17とmacOS Sonomaに ユニバーサルアニメのコレクションが導入されました これはカスタムシンボルを含む シンボルイメージに適用できます これらのアニメーションは バウンスパルスや可変カラー 拡大 縮小 表示 消滅や置換などです
「What's new in SF Symbols 5」を ご覧ください アニメーション自体をさらに 深く掘り下げるため インターフェイスを設計するための ベストプラクティスも含まれます
APIではこれらのアニメーションは 「シンボルエフェクト」と呼ばれ 新しいシンボルフレームワークには それらすべてが含まれます SwiftUIやAppKitまたはUIKitに 無料で付属しますので アプリのビルドにすぐ使えます シンボルフレームワークの非常に 優れた機能は 各エフェクトにドット区切りの名称が 付与されていることです したがってバウンス効果を 作成するのも コードに「.bounce」を記述する だけです
これらのドット区切りの名称は エフェクトの設定方法にも適用されます たとえばシンボルが上または下に バウンスするように指定できますが ほとんどの場合 何も指定する必要はありません フレームワークは自動的に 最も適切な方向を使用します 一部のエフェクトには多くの 設定オプションが備わっています たとえば可変カラーには 3つの異なる設定があります オプションを連鎖させることで 特殊なエフェクトを 簡単に設定できます エフェクト名は 実際のSwiftコードと同じです 制約はありません Xcodeは 名称の各部分を自動補完するので エフェクトが正しく 設定されていない場合 コンパイル時にエラーが発生します 新しいアニメーションを探索する 最良の方法は SF Symbols Appです 新しいアニメーションタブでは 各エフェクトで使用可能な すべての構成オプションについて 学べます ドット区切りのエフェクト名を コピーして コード内で直接使用することも できます すべてのエフェクトタイプと 構成オプションを使用して 非常に多様なアニメーションを 使用できます しかしこれらすべての影響には 小さな一連の動作が含まれます
たとえばバウンスはシンボル上で 1回のみアニメーションを再生 これはディスクリートという動作です 一方スケール効果を追加すると シンボルのスケールレベルが変更 それは無期限に保持されます スケールは不定の動作を サポートします ディスクリートのエフェクトとは異なり インデフィニトの効果は明示的に 削除された場合のみ終了
出現と消滅は 遷移動作をサポートします シンボルをビューの内外に 移動させることが可能です
そして最後の置換は コンテンツの遷移です あるシンボルから別のシンボルへと アニメーション化されます
これが4つの動作です ディスクリート インデフィニト 遷移に コンテンツ遷移です シンボルフレームワークでは それぞれの動作がプロトコルに対応 エフェクトはこれらプロトコルに準拠 することでサポートされる動作を宣言
ここでは利用可能な すべてのエフェクトと サポートされる動作の 内訳を解説します このセッションではこれについて さらに詳しく説明します エフェクトの動作によって どのUIフレームワークAPIが 連携できるかが決まることに なります UIフレームワークAPIで クールなエフェクトをすべて SwiftUIやUIKitにAppKitに 追加する方法についてお話します
SwiftUIには新しいビュー modifier symbolEffectがあります
modifierを追加して目的の エフェクトを渡すだけです ここでvariableColorを渡すと シンボルはデフォルトの可変カラー アニメーションを再生します
AppKitやUIKitでも これを簡単に行えます イメージ ビューで新しい addSymbolEffectメソッドを 使用するだけで 可変カラー効果を追加 ドット構文を使用して 可変カラー効果の構成も可能です ここでは効果変更するのは variableColor.iterative.reversing 異なる可変色カラーの アニメーションが生成されます これはアプリがネットワークに 接続中を示す優れた方法です さまざまなエフェクトを 組み合わせることも可能です ここではスケールアップ効果を 追加します これでシンボルが可変カラーを アニメーション化しながら拡大
これらAPIはシンボルイメージに 無期限の効果を追加する 簡単な方法を提供します インデフィニトの効果は その効果が除去されるまで シンボルの一部を 無期限に変更します
したがってsymbolEffect modifierを使用すると アニメーションを継続的に再生する 可変カラー効果を適用できます ただしエフェクトがアクティブになる タイミング制御も必要です アプリがネットワークに 正常に接続した後 このアニメーションが再生され 続けることは望ましくありません
そのためブール値のisActive パラメータを追加します ここではインターネット接続時のみ エフェクトを適用します アプリの接続が完了するとシンボルの アニメーションがシームレスに終了します
AppKitとUIKitでは removeSymbolEffectメソッドで インデフィニトエフェクトを終了させます 1回のみのアニメーションを実行する ディスクリートのエフェクトについてはどうでしょう? 先ほどこの例としてバウンスに ついて触れました アプリでは特定のイベントに応答して バウンス効果をトリガーするがあります
SwiftUIでは同じsymbolEffect modifierを使用して ディスクリートの効果を追加できます ただしSwiftUIに値を 設定する必要があります 値が変更されるたびにSwiftUIは ディスクリートのエフェクトをトリガーします
押すとシンボルが跳ね返るボタンを 追加しましょう ボタンのハンドラはbounceValueを インクリメントする必要があります SwiftUIはbounceValueの 変更を確認し バウンスをトリガーします AppKitとUIKitで これを行うには 画像ビューにバウンス効果を 追加します Bounceはディスクリートの動作のみを サポートするため 次にエフェクトを追加すると シングルバウンスが実行されます 後でエフェクトを 削除する必要はありません
シンボルを1回だけ バウンスさせるのではない場合 2回跳ねさせてみるのは どうでしょうか? SwiftUIとAppKitにUIKitも オプションパラメーターをサポートしてます 希望の繰り返し回数を ここで指定できます これでエフェクトがトリガーされると シンボルが2回バウンスします ディスクリートの動作が可能なエフェクトは バウンスだけではありません 以前に説明した2つのエフェクト PulseとVariable Colorは ディスクリート動作もサポートします 1回のみのアニメーションを バウンス同様 再生できるわけです 先ほどのバウンスの例を 取り上げてみましょう それをvariableColorに変更 可変カラースイッチは そのディスクリートの動作を使用し 反復しない方法で 適用されるためです
ここでボタンを押すと2つの 可変色サイクルが実行されます
次にコンテンツ遷移効果について 説明します 2つの異なるシンボルイメージ間を アニメーション化する 置換エフェクトはこの主な例です ここでは一時停止記号と再生記号を 切り替える画像を見てみます
SwiftUIには置換で使用できる symbolEffectという 新しいcontentTransition タイプがあります 表示されるシンボルを切り替える ボタンに画像を配置すると その変化がアニメーション化されます AppKitとUIKitでは新しい setSymbolImageメソッドを使用 シンボルコンテンツの遷移を 使用して画像を変更します
最後に独自のアニメーションで シンボルを表示または 非表示にする「出現と消滅」が あります これらの効果は遷移効果として 独自に分類されます その話に入る前にパラレルワールドに ついて話す必要があります ご心配なく 見た目ほど複雑ではありません 1つのユニバースでは イメージは消えますが イメージ ビューは階層内に残ります レイアウトに変更はありません 正方形と円は互いに同じ 距離のままです パラレルワールドでは イメージビューが 階層に追加と削除されます その結果周囲のビューのレイアウトが 変更される場合があります
「出現と消滅」は両方の 動作をサポートしています
最初の動作は出現と消滅が インデフィニト効果であるため可能です
インデフィニト効果の使い方は ご存知かと思います SwiftUIでは.symbolEffect modifierを使用し disappear.を渡します isMoonHiddenの値が更新されると 消滅効果が適用されます
AppKitおよびUIKitでは addSymbolEffectを使用し .disappearまたは .appearを渡します
ここで重要なのは インデフィニト効果がレイアウトを まったく変更しないということです これらはイメージビュー内のシンボルの レンダリングのみを変更します
以上が最初の動作についてでした 周囲のレイアウトが変わるパラレル ワールドにジャンプするにはどうでしょうか?
ここで遷移動作の登場です 遷移エフェクトを SwiftUIの組み込み 遷移modifierで使用すると ビューの挿入またはビュー階層からの ビューの削除をアニメーション化します
遷移動作を使用するよう 前のコードを変換しましょう 条件付きで消滅効果を 適用する代わりに 条件付きシンボルをビュー 階層に追加します
次に遷移modifierを 追加します SwiftUIには次の新しい 遷移タイプがありますが まずご想像のとおり symbolEffectです .disappearを渡すことで シンボルがアニメーションで追加 および削除されるようになりました
自動という独自の遷移効果を 使用することもできます このエフェクトはこのシンボルに 最も適切な 遷移アニメーションを自動的に 実行します
SwiftUIを不使用の場合は 手動で追加して 画像ビューを階層から 削除します UIKitにはエフェクトの完了 ハンドラが備わっています 消えるエフェクトを追加するだけで エフェクトが終了すると 画像ビューを階層から 削除します いかがでしたでしょうか SwiftUIとAppKitに UIKitのシンボル効果について 基本を理解したところで アプリ内でシンボル効果を 別レベルに引き上げるための ヒントをいくつか紹介します まずUIImageViewの 新しいUIKitメソッドが UIBarButtonItemでも 利用可能です これによりシンボルアニメーションを 使用してツールバーに 簡単に命を吹き込めます iOS 17では一部のUIKitコントロールにも シンボルアニメーションを組込み
たとえばUISliderは親指が トラックの端に到達すると 右端の画像をバウンスする ようになりました 新しいisSymbolAnimationEnabled プロパティを使用して UIControlとUIBarButtonItemで これらのアニメーションを 再生させるどうかを制御します
SwiftUIではシンボル効果を 無効にするための 特別な考慮事項もいくつかあります
SwiftUIの他のmodifierと 同様 symbolEffect modifierは ビュー階層を通じて派生します これは親ビューにmodifierを 追加することで複数の画像に 効果を適用できることを意味します ビューがシンボル効果を 継承しないようにするには symbolEffectsRemoved modifierを使用します 表示や消滅に拡大縮小などの 一部のシンボル効果は アニメーションで シンボルの外観を変更します シンボルをアニメーションなしで 拡大したり 最初から見えなくしておくなどが 考えられるでしょう SwiftUIではアニメを無効にした トランザクションを使用して これを行うことが可能です ここではアニメーションを使用せずに scale.upエフェクトを使用します
AppKitやUIKitでは アニメ化されたパラメータを使用 addSymbolEffectで アニメなしで効果を適用します 最後に変数値について説明します
iOS 16とmacOS Venturaでは シンボルの別の手段として 変数値が導入されました 音量レベルや信号強度などの 概念を表します
iOS 17とmacOS Sonomaでは 任意の変数値間のクロスフェードを 大幅に簡素化して 提供できるようになりました
SwiftUIでは何もする 必要はありません こちらのWi-Fiシンボルですが その変数値は何らかの状態に 基づいていますが この場合は現在の信号強度です 信号強度が変化するとWi-Fi シンボルが自動的に更新され 変数値全体が アニメーション化されます AppKitとUIKitでは シンボルコンテンツの 自動遷移を使用します 新しいシンボル画像が異なる 変数値かどうかを検出 その場合は新しい値に クロスフェードします
本日はご参加いただきまして ありがとうございます シンボルをアニメーション化する 方法はたくさんあるので SF Symbols Appを使用して何が 可能かをご覧ください シンボルフレームワークから SwiftUI AppKitやUIKitの 新しいシンボル効果APIを お試しください 最後にアニメーションを採用して アプリのインターフェイスをこれまで 以上に楽しくできます
他のシンボルセッションも チェックしてください シンボルアニメーションに関する ヒューマンインターフェイスや 効果をサポートするためにカスタム シンボルを更新することもできます コーディングを楽しんでくださいね
-
-
6:02 - Symbol effects in SwiftUI
// Symbol effects in SwiftUI Image(systemName: "wifi.router") .symbolEffect(.variableColor.iterative.reversing) .symbolEffect(.scale.up)
-
6:02 - Symbol effects in AppKit and UIKit
let imageView: NSImageView = ... imageView.addSymbolEffect(.variableColor.iterative.reversing) imageView.addSymbolEffect(.scale.up)
-
6:49 - Indefinite symbol effects in SwiftUI
struct ContentView: View { @State var isConnectingToInternet: Bool = true var body: some View { Image(systemName: "wifi.router") .symbolEffect( .variableColor.iterative.reversing, isActive: isConnectingToInternet ) } }
-
7:09 - Indefinite symbol effects in AppKit and UIKit
let imageView: NSImageView = ... imageView.addSymbolEffect(.variableColor.iterative.reversing) // Later, remove the effect imageView.removeSymbolEffect(ofType: .variableColor)
-
8:26 - Discrete symbol effects in SwiftUI
struct ContentView: View { @State var bounceValue: Int = 0 var body: some View { VStack { Image(systemName: "antenna.radiowaves.left.and.right") .symbolEffect( .bounce, options: .repeat(2), value: bounceValue ) Button("Animate") { bounceValue += 1 } } } }
-
8:26 - Discrete symbol effects in AppKit and UIKit
let imageView: NSImageView = ... // Bounce imageView.addSymbolEffect(.bounce, options: .repeat(2))
-
9:40 - Content transition symbol effects in SwiftUI
struct ContentView: View { @State var isPaused: Bool = false var body: some View { Button { isPaused.toggle() } label: { Image(systemName: isPaused ? "pause.fill" : "play.fill") .contentTransition(.symbolEffect(.replace.offUp)) } } }
-
9:57 - Content transition symbol effects in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "play.fill") // Change the image with a Replace effect let pauseImage = UIImage(systemName: "pause.fill")! imageView.setSymbolImage(pauseImage, contentTransition: .replace.offUp)
-
11:14 - Indefinite Appear and Disappear symbol effects in SwiftUI
struct ContentView: View { @State var isMoonHidden: Bool = false var body: some View { HStack { RoundedRectangle(cornerRadius: 5) Image(systemName: "moon.stars") .symbolEffect(.disappear, isActive: isMoonHidden) Circle() } } }
-
11:30 - Indefinite Appear and Disappear symbol effects in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "moon.stars") imageView.addSymbolEffect(.disappear) // Re-appear the symbol imageView.addSymbolEffect(.appear)
-
12:38 - Transition symbol effects in SwiftUI
struct ContentView: View { @State var isMoonHidden: Bool = false var body: some View { HStack { RoundedRectangle(cornerRadius: 5) if !isMoonHidden { Image(systemName: "moon.stars") .transition(.symbolEffect(.disappear.down)) } Circle() } } }
-
12:59 - Appear and Disappear symbol effects in UIKit with completion handler
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "moon.stars") imageView.addSymbolEffect(.disappear) { context in if let imageView = context.sender as? UIImageView, context.isFinished { imageView.removeFromSuperview() } }
-
14:19 - Symbol effect propagation in SwiftUI
VStack { Image(systemName: "figure.walk") .symbolEffectsRemoved() Image(systemName: "car") Image(systemName: "tram") } .symbolEffect(.pulse)
-
14:55 - Effects without animation in SwiftUI
struct ContentView: View { @State var isScaledUp: Bool = false var body: some View { Image(systemName: "iphone.radiowaves.left.and.right") .symbolEffect(.scale.up, isActive: isScaledUp) .onAppear { var transaction = Transaction() transaction.disablesAnimations = true withTransaction(transaction) { isScaledUp = true } } } }
-
15:06 - Effects without animation in AppKit and UIKit
// Effects without animation in AppKit and UIKit let imageView: UIImageView = ... imageView.image = UIImage(systemName: "iphone.radiowaves.left.and.right") imageView.addSymbolEffect(.disappear, animated: false)
-
15:44 - Variable value animations in SwiftUI
struct ContentView: View { @State var signalLevel: Double = 0.5 var body: some View { Image(systemName: "wifi", variableValue: signalLevel) } }
-
16:07 - Variable value animations in AppKit and UIKit
let imageView: UIImageView = ... imageView.image = UIImage(systemName: "wifi", variableValue: 1.0) // Animate to a different Wi-Fi level let currentSignalImage = UIImage( systemName: "wifi", variableValue: signalLevel )! imageView.setSymbolImage(currentSignalImage, contentTransition: .automatic)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。