WWDC Quick Look 💓 By SwiftGGTeam
Animate with springs

Animate with springs

元の動画を見る

ハイライト

SwiftUI は、iOS 17 でデフォルトのアニメーションを easyInOut から物理ベースのスプリングに変更し、従来の質量/剛性/減衰を置き換えるためにデュレーション + バウンスの 2 つの直感的なパラメーターを導入し、また、Springモデル タイプを使用すると、開発者はカスタム アニメーションで Apple のバネ計算ロジックを再利用できます。

主な内容

春のアニメーションが優れている理由

Jacob は SwiftUI チームからスタートし、例としてスイッチ ボタンのノブ アニメーションを使用しました。アニメーションの核となる価値の 1 つは、連続性を提供することです。オブジェクトが A から B に移動するとき、位置と速度の両方が連続的​​に変化する必要があります。そうしないと、唐突に感じられます。

イーズイン/アウト アニメーションは、静的な開始には適切に機能しますが、ジェスチャで使用すると、初期速度を表現できないという致命的な欠陥があります。ユーザーがドラッグして放すと、easeInOut アニメーションは突然停止し、再び開始します。リニア アニメーションでは開始点と終了点で速度が急激に変化しますが、これも適切ではありません。

Spring アニメーションには 2 つの主要な利点があります。

  1. 速度と位置は両方とも連続的です: スプリングは任意の初期速度を受け入れることができ、アニメーションはジェスチャの終了時の速度から自然に移行します。
  2. より自然な動き: 現実の物理世界のバネモデルに基づいて、オブジェクトの動きに対する人間の直感に合わせて、ゆっくりと減速して停止します。

ばねの物理モデル

(08:35) スプリング アニメーションは、次の 3 つの物理プロパティによって定義されます。

  • mass (質量): オブジェクトの質量
  • 剛性: スプリングの剛性
  • ダンピング (ダンピング): システムの摩擦

しかし、これらのパラメータは開発者にとって十分に直観的ではありません。SwiftUI には、より使いやすいパラメータが導入されています。

  • 期間: アニメーションの知覚される期間
  • バウンス: バウンス レベル、-1.0 ~ 1.0

3種類のスプリング:

  • 弾性 (弾性 > 0): 過度のダンピング、目標位置をオーバーシュートします。
  • スムーズ (バウンス = 0): 重要な減衰、ゆっくりとターゲットに漸近します
  • フラット化 (バウンス < 0): 減衰が少なく、ターゲットへのフラットなアプローチ

複数属性の連携

(08:05) iOS のアプリ起動アニメーションは、春のアニメーションの典型的なケースです。アトリビュートが異なれば、異なるスプリング パラメータと異なる開始時間と終了時間を使用して、自然でスムーズなエフェクトを作成します。異なる属性を同時に開始および終了する必要はありません。この「凹凸」がアニメーションをよりリアルに感じさせます。

##詳細

スプリング プリセットの使用

(18:00) SwiftUI には 3 つの組み込みスプリング プリセットが用意されています。

withAnimation(.snappy) {
    // Changes
}

キーポイント:

  • .snappy: 少量のバウンスで、ほとんどのインタラクションに適しています。
  • .smooth: 跳ね返りがなく、微妙な変化に適しています。
  • .bouncy: より弾みがあり、活発なインタラクションに適しています。

カスタム プリセット パラメータ:

withAnimation(.snappy(duration: 0.4)) {
    // 自定义持续时间
}

withAnimation(.snappy(extraBounce: 0.1)) {
    // 在预设基础上增加弹跳
}

春をカスタマイズする

(18:37) 完全にカスタマイズされたスプリング:

withAnimation(.spring(duration: 0.6, bounce: 0.2)) {
    // Changes
}

// UIKit
UIView.animate(duration: 0.6, bounce: 0.2) {
    // Changes
}

// Core Animation
let animation = CASpringAnimation(perceptualDuration: 0.6, bounce: 0.2)

キーポイント:

  • durationそしてbounceSwiftUI、UIKit、およびコアアニメーション間で統一されたパラメータ
  • bounce範囲は-1.0~1.0です。
  • 0 は滑らかを意味し、正の値は弾力性を意味し、負の値は平らであることを意味します

スプリングモデルの種類

18:57Spring型は独立して使用できます。

let mySpring = Spring(duration: 0.5, bounce: 0.2)
let (mass, stiffness, damping) = (mySpring.mass, mySpring.stiffness, mySpring.damping)

従来のパラメータを使用して作成:

let otherSpring = Spring(mass: 1, stiffness: 100, damping: 10)
withAnimation(.spring(otherSpring)) {
    // Changes
}

キーポイント:

  • 持続時間/バウンスと質量/剛性/減衰を切り替えることができます ・パラメータ換算式:
    • stiffness = (2π ÷ duration)²
    • damping = 1 - 4π × bounce ÷ duration(bounce ≥ 0)
    • damping = 4π ÷ (duration + 4π × bounce)(bounce < 0)

春を評価する

(19:35) いつでもスプリングのステータスをクエリできます。

let mySpring = Spring(duration: 0.4, bounce: 0.2)
let value = mySpring.value(target: 1, time: time)
let velocity = mySpring.velocity(target: 1, time: time)

キーポイント:

  • value指定された時刻におけるスプリングの位置を返します。
  • velocity指定された時刻におけるバネの速度を返します。
  • カスタム アニメーション、シミュレーション、データの視覚化に最適

カスタム アニメーションで Spring を使用する

20:15CustomAnimationスプリング ロジックを再利用します。

func animate<V: VectorArithmetic>(
    value: V, time: Double, context: inout AnimationContext<V>
) -> V? {
    spring.value(
        target: value, initialVelocity: context.initialVelocity,
        time: effectiveTime(time: time, context: context))
}

キーポイント:

  • 電話spring.value補間結果の取得
  • 着信initialVelocityジェスチャー速度を維持する
  • effectiveTime処理時間のマッピング

バウンス値を選択します

(21:07) さまざまなバウンス値の感触:

// 无弹跳 - 最通用
withAnimation(.spring(duration: 0.5)) {
    isActive.toggle()
}

// 小弹跳 - 更有活力
withAnimation(.spring(duration: 0.5, bounce: 0.15)) {
    isActive.toggle()
}

// 大弹跳 - 更活泼
withAnimation(.spring(duration: 0.5, bounce: 0.3)) {
    isActive.toggle()
}

キーポイント:

  • 疑わしい場合はバウンス 0 (スムーズ) を使用します。これが最も汎用性の高い選択肢です。
  • 生き生きとした感触が必要な場合は、バウンスを追加します。
  • ジェスチャーの最後のアニメーションは、より物理的なものであるため、バウンスの使用に適しています。
  • 0.4 を超えるバウンスは誇張されすぎる可能性があるため、使用には注意してください
  • アプリ内でアニメーション スタイルの一貫性を保つ

Settling Duration

(16:45) 春のアニメーションは理論的には完全に停止することはなく、どんどん小さく動くだけです。SwiftUI は「整定期間」を使用して、アニメーションを削除するタイミング、つまり動きが小さすぎて目立たない場合を決定します。

ただし、セトリングにかかる​​時間は予測できないことに注意してください。アニメーションが「ほぼ終了」したときに UI を変更する必要がある場合は、設定期間ではなく知覚期間に基づく SwiftUI の新しい完了ハンドラーを使用してください。

重要ポイント

  1. グローバル置換easeInOut
  • 対処方法: すべてを追加します。withAnimationそして.animation()Spring へのデフォルトの呼び出しが明示的に変更されました。
  • 実行する価値がある理由: iOS 17 にはデフォルトでスムーズ スプリングが備わっていますが、これを明示的に指定することで意図がより明確になり、パラメーターの微調整が可能になります。
  • 開始方法: プロジェクト内のすべてのアイテムを検索します.easeInOutそして裸withAnimation、に置き換えられます.spring(duration:bounce:)
  1. ジェスチャー主導の弾性インタラクション
  • やるべきこと: ドラッグ、スライド、その他のジェスチャに春の終了アニメーションを追加する
  • 実行する価値がある理由: スプリングはジェスチャーの速度を自動的に継承し、手を放した後のアニメーションは自然でスムーズであり、手動で速度を計算する必要はありません。
  • 開始方法: でonEnded中国語での使用withAnimation(.spring)最終状態を設定すると、SwiftUI が速度配信を自動的に処理します
  1. 中断可能なアニメーション システム
  • 機能: 新しいアニメーションとスムーズなトランジションによってアニメーションを中断可能にします。
  • 実行する価値がある理由: スプリング アニメーションが中断されると、現在の速度が新しいアニメーションの初期速度として保持され、ユーザー エクスペリエンスが一貫したものになります。
  • 開始方法: 必ずスプリング アニメーションを使用し、新しい状態が到着したときにそれらを直接呼び出してください。withAnimation(.spring)ステータスを更新する
  1. ブランドモーションデザインシステム
  • やるべきこと: チーム向けに統一されたアニメーション パラメータ仕様のセットを定義する
  • 実行する価値がある理由: 継続時間 + バウンスの 2 つのパラメーターは、ブランドのトーン (真面目か活発か) を表現するのに十分であり、チーム全体にとって理解しやすいものです。
  • 始め方: 定義extension Animation { static let brand = .spring(duration: 0.4, bounce: 0.1) }、すべてのアプリを一律に使用できます
  1. スプリング駆動のデータ視覚化
  • やるべきこと: Spring モデルの計算を使用してカスタム チャートやゲームの物理演算を駆動する
  • 実行する価値がある理由: 物理シミュレーションを自分で実装することなく、Apple の最適化されたスプリング数学を再利用できます。
  • 開始方法: 作成するSpring例:TimelineViewまたはゲームループ内で呼び出されますspring.value(target:time:)現在の値を取得する

関連セッション

コメント

GitHub Issues · utterances