Animation: frame vs layout constraints
最初のトピックとしてアニメーションを選択しました.アプリケーションを作成するときに適切なアニメーションを適用するのは容易ではありませんこの授業では、アニメーションの基礎知識を紹介します.
Animation
のアニメーションがなければ、アプリケーションは硬く感じるかもしれません.アニメーションを使用すると、アプリケーションの可用性が向上します. のアニメーションがあれば、ユーザーはもっと投入されます!
これは、ビューの状態が時間とともに変化することを意味します.
時間:ビューの変化はどのくらい続きますか? 終了:アニメーション終了時の最終ビューの状態 値:ビューはどのくらい変化しますか?(ex.移動距離、拡大倍率) 実習の準備をする
Animation
必要な理由
定義#テイギ#
これは、ビューの状態が時間とともに変化することを意味します.
アニメーションの3要素
animation API
UIView.animate(withDuration: 1.0, // 애니메이션의 지속시간
delay: 1.0, // 애니메이션이 시작하기 전에 기다릴 시간
options: .curveEaseInOut, // 애니메이션 옵션
animations: {}, // 애니메이션 내용
completion: { _ in return } // 애니메이션이 끝나면 실행할 클로저
)
実習の準備をする
アニメーションのターゲットとして青い円を用意し、アニメーションを開始するボタンを用意します.import UIKit
class VC1: UIViewController {
// MARK: Properties
// 파란색 원
let circle: UIView = {
let view = UIView()
view.frame.size = CGSize(width: 100, height: 100)
view.layer.cornerRadius = 100 / 2
view.backgroundColor = .blue
return view
}()
// 애니메이션 버튼
let animationButton: UIButton = {
let button = UIButton()
button.setTitle("animate!", for: .normal)
button.setTitleColor(.black, for: .normal)
button.addTarget(self, action: #selector(animateCircle), for: .touchUpInside)
return button
}()
// MARK: LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureUI()
}
// MARK: Selector
@objc func animateCircle() {
UIView.animate(withDuration: 1.0, animations: {
// 애니메이션 정의
})
}
// MARK: Helpers
func configureUI() {
view.addSubview(circle)
circle.frame.origin = CGPoint(x: view.frame.width / 2 - 50, y: 100)
view.addSubview(animationButton)
animationButton.translatesAutoresizingMaskIntoConstraints = false
animationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
animationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
}
}
フレームを使用したアニメーションの作成
フレームワークは、オブジェクトの絶対位置と絶対サイズを定義します.フレームは原点と寸法で構成されています.原点は原点(左上隅)の位置、寸法は大きさを表します.
フレーム値の原点値を変更することで、オブジェクトを移動できます.@objc func animateCircle() {
UIView.animate(withDuration: 1.0, animations: {
self.circle.frame.origin.y = 200
})
}
レイアウトコンストレイントを使用したアニメーションの作成
実戦では、フレーム内のオブジェクトをどこかに置くことはめったにありません.ほとんどの場合、レイアウトコンストレイントを定義して位置を定義します.これらのコンストレイントは、他のオブジェクトとの相対的な位置を指定します.そこで、レイアウトコンストレイントを使用してアニメーションを定義する方法についても説明します.
""レイアウトコンストレイント"を使用してアニメーションを作成するには、アニメーション前のレイアウトコンストレイントをメンバー変数として宣言する必要があります.これは、対応するレイアウトコンストレイントを無効にし、新しいレイアウトコンストレイントを適用する必要があるためです.let circle: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
view.heightAnchor.constraint(equalToConstant: 100).isActive = true
view.layer.cornerRadius = 100 / 2
view.backgroundColor = .blue
return view
}()
lazy var beforeAnimation = self.circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100)
// 처음에 화면에 띄우는 헬퍼 함수
func configureUI() {
view.addSubview(circle)
circle.translatesAutoresizingMaskIntoConstraints = false
circle.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
beforeAnimation.isActive = true
view.addSubview(animationButton)
animationButton.translatesAutoresizingMaskIntoConstraints = false
animationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
animationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
}
レイアウトコンストレイントの使用方法はフレームワークとは異なります.アニメーションモジュールを実装する前に、レイアウトコンストレイントを適用してください.キャンセルするレイアウト制約をメンバー変数として削除する理由は、次のコレクタ関数にアクセスするためです.既存のレイアウトコンストレイントと新しいレイアウトコンストレイントが競合するため、キャンセルしないとアニメーションは実行されません.
新しいレイアウトコンストレイントが適用されたからといって、すぐにビューを変更することはありません.アニメーションモジュールでlayoutifNeeded()メソッドを使用して更新する必要があります.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
🚫 メンバー変数として単独で減算するほか、以下のように同じレイアウトコンストレイント、=falseを書き直すことでキャンセルできるという意見もたまにあります.これではだめです.同じレイアウトコンストレイントを再適用しても、異なるメモリ領域に格納されます.したがって、既存のtrueに設定されたレイアウトコンストレイントはfalseではありません.@objc func animateCircle() {
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100) = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200) = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
いくつかの適用アニメーション
基本アニメーションに加えて、いくつかの特殊なアニメーションAPIも提供されています.ここで簡単に紹介します各パラメータの意味については、本書を参照してください.
スプリングアニメーション
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0,
delay: 0.2,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 2,
animations: {
self.view.layoutIfNeeded()
})
}
反転アニメーションを追加
アニメーションではなくAPIでアニメーションを使用できます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.transition(with: circle,
duration: 1,
options: .transitionFlipFromLeft,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
連続アニメーション
アニメーションが終了したら、タイマーを使用して次のアニメーションを続行します.
完了パラメータの使用
animateメソッドのcompletionは、アニメーションが終了した後に実行するモジュールを定義するパラメータです.ここに別のアニメーションを挿入すると、アニメーションを連続的に実行できます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() },
completion: { _ in
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
})
}
タイマーの使用(DispatchQueue.main.asyncAfter)
タイマーの使い方.別のアニメーションを最初のアニメーションの持続時間の後に続けます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
}
}
終了時..。
story boardを使用してoutletをインポートしたlayoutコンストレイントは多くのアニメーションを作成しましたが、コード定義のlayoutコンストレイントを使用して初めて作成され、途中で多くのエラーが発生しました.やはりコードは自分で作成して実行して進歩した
もっと素晴らしいアニメを作る日まで頑張ります
Reference
この問題について(Animation: frame vs layout constraints), 我々は、より多くの情報をここで見つけました
https://velog.io/@comdongsam/1.-Animation-사용하기-frame-vs-layout-constraints
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import UIKit
class VC1: UIViewController {
// MARK: Properties
// 파란색 원
let circle: UIView = {
let view = UIView()
view.frame.size = CGSize(width: 100, height: 100)
view.layer.cornerRadius = 100 / 2
view.backgroundColor = .blue
return view
}()
// 애니메이션 버튼
let animationButton: UIButton = {
let button = UIButton()
button.setTitle("animate!", for: .normal)
button.setTitleColor(.black, for: .normal)
button.addTarget(self, action: #selector(animateCircle), for: .touchUpInside)
return button
}()
// MARK: LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureUI()
}
// MARK: Selector
@objc func animateCircle() {
UIView.animate(withDuration: 1.0, animations: {
// 애니메이션 정의
})
}
// MARK: Helpers
func configureUI() {
view.addSubview(circle)
circle.frame.origin = CGPoint(x: view.frame.width / 2 - 50, y: 100)
view.addSubview(animationButton)
animationButton.translatesAutoresizingMaskIntoConstraints = false
animationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
animationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
}
}
フレームワークは、オブジェクトの絶対位置と絶対サイズを定義します.フレームは原点と寸法で構成されています.原点は原点(左上隅)の位置、寸法は大きさを表します.
フレーム値の原点値を変更することで、オブジェクトを移動できます.
@objc func animateCircle() {
UIView.animate(withDuration: 1.0, animations: {
self.circle.frame.origin.y = 200
})
}
レイアウトコンストレイントを使用したアニメーションの作成
実戦では、フレーム内のオブジェクトをどこかに置くことはめったにありません.ほとんどの場合、レイアウトコンストレイントを定義して位置を定義します.これらのコンストレイントは、他のオブジェクトとの相対的な位置を指定します.そこで、レイアウトコンストレイントを使用してアニメーションを定義する方法についても説明します.
""レイアウトコンストレイント"を使用してアニメーションを作成するには、アニメーション前のレイアウトコンストレイントをメンバー変数として宣言する必要があります.これは、対応するレイアウトコンストレイントを無効にし、新しいレイアウトコンストレイントを適用する必要があるためです.let circle: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
view.heightAnchor.constraint(equalToConstant: 100).isActive = true
view.layer.cornerRadius = 100 / 2
view.backgroundColor = .blue
return view
}()
lazy var beforeAnimation = self.circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100)
// 처음에 화면에 띄우는 헬퍼 함수
func configureUI() {
view.addSubview(circle)
circle.translatesAutoresizingMaskIntoConstraints = false
circle.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
beforeAnimation.isActive = true
view.addSubview(animationButton)
animationButton.translatesAutoresizingMaskIntoConstraints = false
animationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
animationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
}
レイアウトコンストレイントの使用方法はフレームワークとは異なります.アニメーションモジュールを実装する前に、レイアウトコンストレイントを適用してください.キャンセルするレイアウト制約をメンバー変数として削除する理由は、次のコレクタ関数にアクセスするためです.既存のレイアウトコンストレイントと新しいレイアウトコンストレイントが競合するため、キャンセルしないとアニメーションは実行されません.
新しいレイアウトコンストレイントが適用されたからといって、すぐにビューを変更することはありません.アニメーションモジュールでlayoutifNeeded()メソッドを使用して更新する必要があります.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
🚫 メンバー変数として単独で減算するほか、以下のように同じレイアウトコンストレイント、=falseを書き直すことでキャンセルできるという意見もたまにあります.これではだめです.同じレイアウトコンストレイントを再適用しても、異なるメモリ領域に格納されます.したがって、既存のtrueに設定されたレイアウトコンストレイントはfalseではありません.@objc func animateCircle() {
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100) = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200) = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
いくつかの適用アニメーション
基本アニメーションに加えて、いくつかの特殊なアニメーションAPIも提供されています.ここで簡単に紹介します各パラメータの意味については、本書を参照してください.
スプリングアニメーション
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0,
delay: 0.2,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 2,
animations: {
self.view.layoutIfNeeded()
})
}
反転アニメーションを追加
アニメーションではなくAPIでアニメーションを使用できます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.transition(with: circle,
duration: 1,
options: .transitionFlipFromLeft,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
連続アニメーション
アニメーションが終了したら、タイマーを使用して次のアニメーションを続行します.
完了パラメータの使用
animateメソッドのcompletionは、アニメーションが終了した後に実行するモジュールを定義するパラメータです.ここに別のアニメーションを挿入すると、アニメーションを連続的に実行できます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() },
completion: { _ in
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
})
}
タイマーの使用(DispatchQueue.main.asyncAfter)
タイマーの使い方.別のアニメーションを最初のアニメーションの持続時間の後に続けます.@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
}
}
終了時..。
story boardを使用してoutletをインポートしたlayoutコンストレイントは多くのアニメーションを作成しましたが、コード定義のlayoutコンストレイントを使用して初めて作成され、途中で多くのエラーが発生しました.やはりコードは自分で作成して実行して進歩した
もっと素晴らしいアニメを作る日まで頑張ります
Reference
この問題について(Animation: frame vs layout constraints), 我々は、より多くの情報をここで見つけました
https://velog.io/@comdongsam/1.-Animation-사용하기-frame-vs-layout-constraints
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
let circle: UIView = {
let view = UIView()
view.widthAnchor.constraint(equalToConstant: 100).isActive = true
view.heightAnchor.constraint(equalToConstant: 100).isActive = true
view.layer.cornerRadius = 100 / 2
view.backgroundColor = .blue
return view
}()
lazy var beforeAnimation = self.circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100)
// 처음에 화면에 띄우는 헬퍼 함수
func configureUI() {
view.addSubview(circle)
circle.translatesAutoresizingMaskIntoConstraints = false
circle.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
beforeAnimation.isActive = true
view.addSubview(animationButton)
animationButton.translatesAutoresizingMaskIntoConstraints = false
animationButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
animationButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -100).isActive = true
}
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
@objc func animateCircle() {
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100) = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200) = true
UIView.animate(withDuration: 1.0, animations: {
self.view.layoutIfNeeded()
})
}
基本アニメーションに加えて、いくつかの特殊なアニメーションAPIも提供されています.ここで簡単に紹介します各パラメータの意味については、本書を参照してください.
スプリングアニメーション
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0,
delay: 0.2,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 2,
animations: {
self.view.layoutIfNeeded()
})
}
反転アニメーションを追加
アニメーションではなくAPIでアニメーションを使用できます.
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.transition(with: circle,
duration: 1,
options: .transitionFlipFromLeft,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
連続アニメーション
アニメーションが終了したら、タイマーを使用して次のアニメーションを続行します.
完了パラメータの使用
animateメソッドのcompletionは、アニメーションが終了した後に実行するモジュールを定義するパラメータです.ここに別のアニメーションを挿入すると、アニメーションを連続的に実行できます.
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() },
completion: { _ in
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
})
}
タイマーの使用(DispatchQueue.main.asyncAfter)
タイマーの使い方.別のアニメーションを最初のアニメーションの持続時間の後に続けます.
@objc func animateCircle() {
beforeAnimation.isActive = false
circle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 200).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.beforeAnimation2.isActive = false
self.circle.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 100).isActive = true
UIView.animate(withDuration: 1.0, animations: { self.view.layoutIfNeeded() })
}
}
終了時..。
story boardを使用してoutletをインポートしたlayoutコンストレイントは多くのアニメーションを作成しましたが、コード定義のlayoutコンストレイントを使用して初めて作成され、途中で多くのエラーが発生しました.やはりコードは自分で作成して実行して進歩した
もっと素晴らしいアニメを作る日まで頑張ります
Reference
この問題について(Animation: frame vs layout constraints), 我々は、より多くの情報をここで見つけました
https://velog.io/@comdongsam/1.-Animation-사용하기-frame-vs-layout-constraints
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について(Animation: frame vs layout constraints), 我々は、より多くの情報をここで見つけました https://velog.io/@comdongsam/1.-Animation-사용하기-frame-vs-layout-constraintsテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol