アニメーションを作成することへの恐怖心を克服するのに CAAnimation がどのように役立ったか
この記事では、iOS で CA Animations を使用してスムーズなアニメーションを作成することに焦点を当てています。
iOS を使った最初の数日間、デザイナーが私のところに来て、彼らが取り組んでいるアプリにアニメーションを追加するように頼むたびに、私は非常に緊張しました.
アニメーションのデザインを思いつくのは簡単だと思っていましたが、一方でそれを実装するのは非常に難しい作業でした.
実装については、Google、StackOverflow、および仲間から助けを得るでしょう。
その過程で、私はアニメーションに対する恐怖症を発症し、常にそれらを避けようとしました.しかし、ある日すべてが変わりました。
CAAnimation の検索
ある時、ビュー内の一連の画像をアニメーション化する必要がありました。それで、私の最初のステップは何でしたか?もちろん、StackOverflow です!
最初のリンクがコードを取得しました。
let image_1 = UIImage(named: "image-1")!
let image_2 = UIImage(named: "image-2")!
let image_3 = UIImage(named: "image-3")!
let images = [image_1, image_2, image_3]
let animatedImage = UIImage.animatedImage(with: images, duration: 2.0)
imageView.image = animatedImage
かなり簡単ですよね?そんなに簡単だったら、私はこの記事を書いていないでしょう.
これは必要なアニメーションです:
そして、おそらく明らかになったように、私はそれに近づきませんでした。私は立ち往生しました。そのアニメーションでこれほど多くのカスタマイズを行い、それらすべてを同期するにはどうすればよいでしょうか?
その後、同僚から CAAnimation を試すように言われました。私はそれについて読んで、サンプルプロジェクトで試しました。驚いたことに、それは非常に強力で使いやすいものでした。
コア アニメーションとは
Core Animation を使用すると、CPU 使用率がほぼゼロで複数のアニメーションを実行できます。
高いフレーム レートと、非常に少ないコードで使用できる多くのカスタマイズが可能になります。
詳細については、こちらのドキュメントをご覧ください:https://developer.apple.com/documentation/quartzcore
数時間で基本的な実装を行うことができました:
func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
firstImageView.layer.add(basicAnimation1, forKey: "position")
let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
secondImageView.layer.add(basicAnimation2, forKey: "position")
self.addNextImage(forImageView: firstImageView)
}
func getBasicAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CABasicAnimation {
let basicAnimation = CABasicAnimation(keyPath: "position")
basicAnimation.fromValue = NSValue(cgPoint: initialPos)
basicAnimation.toValue = NSValue(cgPoint: finalPos)
basicAnimation.duration = 1
basicAnimation.isRemovedOnCompletion = false
basicAnimation.fillMode = CAMediaTimingFillMode.forwards
basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
return basicAnimation
}
この実装では、CABasicAnimation を使用しました .
CABasicAnimation クラスは、レイヤー プロパティ (背景色、不透明度、位置、スケールなど) を 2 つの値の間でアニメーション化するのに役立ちます。開始値と終了値を指定するだけで、あとは処理されます。ここで詳しく説明されているように、アニメーションは次の実行ループですぐに開始されます。
さて、問題に戻りましょう。
これを実装するために、2 つの画像ビューを取得し、それらに 2 つの個別の画像を追加しました。その後、CAAnimation を使用して次々とアニメーション化を続けました。
ソースコードはこちらにあります。
最後の gif を調べると、何かがおかしいことがわかります。ギフト ボックスの最初の画像が見えなくなる前に、ヘッドフォンが短く点滅し、画像が上に移動します。
なぜこれが起こっているのですか?
これは、アニメーションを画像ビューに追加するとすぐに、次の画像をそのビューに追加するためです (行番号 5 と 6):
private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
firstImageView.layer.add(basicAnimation1, forKey: "position")
let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
secondImageView.layer.add(basicAnimation2, forKey: "position")
self.addNextImage(forImageView: firstImageView)
}
ここでは、アニメーションで両方の画像を同期する方法の問題に取り組んでいます。しかし、CAAnimation には常に解決策があります。
CA トランザクション
CA トランザクションは、複数のアニメーションを一緒に同期するのに役立ちます。一緒にバンドルされているすべてのアニメーションがすべて同時に開始されるようにします。
また、アニメーションに完了ブロックを与えることもできます。これは、1 つのバンドル内のすべてのアニメーションが完了したときに実行されます。
詳しくはこちらをご覧ください。
private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
CATransaction.begin()
CATransaction.setCompletionBlock {
self.addNextImage(forImageView: firstImageView)
}
let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
firstImageView.layer.add(basicAnimation1, forKey: "position")
CATransaction.commit()
let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
secondImageView.layer.add(basicAnimation2, forKey: "position")
}
CATransaction.begin()
を書くことから始めます .次に、同期させたいすべてのアニメーションを作成します。最後に、CATransaction.commit()
を呼び出します これにより、ブロック内でアニメーションが開始されます。
アニメーションがどのように見えるか見てみましょう:
最後に、アニメーションにスプリング エフェクトを追加する必要がありました。ありがたいことに、CAAnimation にはこれに対する解決策もありました。
CA 春のアニメーション
CA Spring Animation をレイヤーに追加すると、レイヤーにバネのような効果が与えられ、バネによってターゲットに向かって引っ張られているように見えます。
レイヤーがターゲットから離れているほど、レイヤーに向かう加速度が大きくなります。
スプリングのダンピングや剛性など、物理ベースのアトリビュートを制御できます。 – ドキュメント
詳細については、Apple のドキュメント (https://developer.apple.com/documentation/quartzcore/caspringanimation) を参照してください。
これを既存のコードに実装しましょう:
private func getSpringAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CASpringAnimation {
let basicAnimation = CASpringAnimation(keyPath: "position")
basicAnimation.fromValue = NSValue(cgPoint: initialPos)
basicAnimation.toValue = NSValue(cgPoint: finalPos)
basicAnimation.duration = basicAnimation.settlingDuration
basicAnimation.damping = 14
basicAnimation.initialVelocity = 5
basicAnimation.isRemovedOnCompletion = false
basicAnimation.fillMode = CAMediaTimingFillMode.forwards
return basicAnimation
}
私の仕事はここで終わりです。
要約すると、CA Animations を使用する利点のいくつかを次に示します。
- 使い方も実装も簡単
- 利用可能なカスタマイズがたくさんあります
- 複数のアニメーションを同期できます
- CPU 使用率がほぼゼロ
これらはメリットのほんの一部です。可能性は無限大です。
今では、アニメーションの要件が発生するたびに、自信を持って設計および実装しています。そして、これを読んだあなたも同じように感じていただければ幸いです。
提案やフィードバックがあればお気軽にお寄せください。
-
Stuxnet:概要と仕組み
Stuxnet とは Stuxnet は、イランの核施設を攻撃するために設計および展開されたコンピューター ワームです。物理インフラに影響を与えたおそらく世界初のサイバー兵器である Stuxnet は、イランの核遠心分離機を標的とし、重要な軍事能力に損害を与えて破壊し、イランの核計画に大きな混乱を引き起こしました。 誰が Stuxnet を作成したのかは公式には明らかにされていませんが、このワームは米国とイスラエル政府によって共同で開発されたと広く理解されています。イランの核兵器計画の進行にますます懸念を抱く両国政府は、核研究開発センターに対する空爆を含む、さまざまな選択肢を検討しました。
-
アニメーションを無効にして Windows 10 をより速く感じる方法
Windows 10 では、Windows デスクトップに多くの設計改良が加えられました。特に、Microsoft の新しい Fluent Design System が導入されて以来、モーションとアニメーションはユーザー インターフェース全体でより一般的になりました。 Windows 10 アニメーションを無効にする Windows 10 のアニメーションは、より洗練された合理化された印象を与えることができますが、スピードという欠点もあります。 [スタート] メニューを開くたびに、すべてのタイルがアニメーション化されるまでしばらく待つ必要があります。新しいアプリを起動するか、タスクバーに最