ハイライト
SwiftUI は、iOS 17 でデフォルトのアニメーションを easyInOut から物理ベースのスプリングに変更し、従来の質量/剛性/減衰を置き換えるためにデュレーション + バウンスの 2 つの直感的なパラメーターを導入し、また、
Springモデル タイプを使用すると、開発者はカスタム アニメーションで Apple のバネ計算ロジックを再利用できます。
主な内容
春のアニメーションが優れている理由
Jacob は SwiftUI チームからスタートし、例としてスイッチ ボタンのノブ アニメーションを使用しました。アニメーションの核となる価値の 1 つは、連続性を提供することです。オブジェクトが A から B に移動するとき、位置と速度の両方が連続的に変化する必要があります。そうしないと、唐突に感じられます。
イーズイン/アウト アニメーションは、静的な開始には適切に機能しますが、ジェスチャで使用すると、初期速度を表現できないという致命的な欠陥があります。ユーザーがドラッグして放すと、easeInOut アニメーションは突然停止し、再び開始します。リニア アニメーションでは開始点と終了点で速度が急激に変化しますが、これも適切ではありません。
Spring アニメーションには 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:57)Spring型は独立して使用できます。
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:15)CustomAnimationスプリング ロジックを再利用します。
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 の新しい完了ハンドラーを使用してください。
重要ポイント
- グローバル置換easeInOut
- 対処方法: すべてを追加します。
withAnimationそして.animation()Spring へのデフォルトの呼び出しが明示的に変更されました。 - 実行する価値がある理由: iOS 17 にはデフォルトでスムーズ スプリングが備わっていますが、これを明示的に指定することで意図がより明確になり、パラメーターの微調整が可能になります。
- 開始方法: プロジェクト内のすべてのアイテムを検索します
.easeInOutそして裸withAnimation、に置き換えられます.spring(duration:bounce:)
- ジェスチャー主導の弾性インタラクション
- やるべきこと: ドラッグ、スライド、その他のジェスチャに春の終了アニメーションを追加する
- 実行する価値がある理由: スプリングはジェスチャーの速度を自動的に継承し、手を放した後のアニメーションは自然でスムーズであり、手動で速度を計算する必要はありません。
- 開始方法: で
onEnded中国語での使用withAnimation(.spring)最終状態を設定すると、SwiftUI が速度配信を自動的に処理します
- 中断可能なアニメーション システム
- 機能: 新しいアニメーションとスムーズなトランジションによってアニメーションを中断可能にします。
- 実行する価値がある理由: スプリング アニメーションが中断されると、現在の速度が新しいアニメーションの初期速度として保持され、ユーザー エクスペリエンスが一貫したものになります。
- 開始方法: 必ずスプリング アニメーションを使用し、新しい状態が到着したときにそれらを直接呼び出してください。
withAnimation(.spring)ステータスを更新する
- ブランドモーションデザインシステム
- やるべきこと: チーム向けに統一されたアニメーション パラメータ仕様のセットを定義する
- 実行する価値がある理由: 継続時間 + バウンスの 2 つのパラメーターは、ブランドのトーン (真面目か活発か) を表現するのに十分であり、チーム全体にとって理解しやすいものです。
- 始め方: 定義
extension Animation { static let brand = .spring(duration: 0.4, bounce: 0.1) }、すべてのアプリを一律に使用できます
- スプリング駆動のデータ視覚化
- やるべきこと: Spring モデルの計算を使用してカスタム チャートやゲームの物理演算を駆動する
- 実行する価値がある理由: 物理シミュレーションを自分で実装することなく、Apple の最適化されたスプリング数学を再利用できます。
- 開始方法: 作成する
Spring例:TimelineViewまたはゲームループ内で呼び出されますspring.value(target:time:)現在の値を取得する
関連セッション
- SwiftUI アニメーションを探索する — SwiftUI アニメーション システムの完全な原理
- SwiftUI で高度なアニメーションを使いこなす — キーフレームとマルチステージ アニメーション
- SwiftUI の要点 — SwiftUI の基本概念
- スクロール ビューを超えて — ScrollView のアニメーションとトランジション
コメント
GitHub Issues · utterances