背景
UIViewクラスにはanimateというメソッドが用意されており、下記のようにシンプルにアニメーションを実装することができます。
UIView.animate(withDuration: 3) {
self.testView.frame.origin.y += 50
}
ただしこのようなアニメーションを繰り返し行いたい場合、例えば5秒毎にViewを上下に行ったり来たりさせるといったアニメーションを実装するには、若干の工夫が必要になります。本記事では、Timerクラスを用いて永続的なアニメーションを行う手法を紹介します。
アニメーションの実装
まず、下記のようにアニメーションを行うメソッドを定義しておきます。この例では、testViewのframe.origin.yが0の場合は下に50point移動し、そうでない場合は0の位置に移動するというアニメーションを0.3秒で行うように指定しています。
※後にselectorとして使用可能なように、メソッドの接頭詞に@objcを付けています。
@objc func animate() {
UIView.animate(withDuration: 0.3) {
if self.testView.frame.origin.y == 0 {
self.testView.frame.origin.y += 50
} else {
self.testView.frame.origin.y = 0
}
}
}
Timerの設定
次にTimerの設定を行います。下記の例では、5秒毎にanimateメソッドを呼び続けるようにTimerをセットしています。こうすることで、一定間隔で上記のanimateメソッドが呼び出され、testViewが上下に50ポイントずつ動き続けるアニメーションを実装することができます。
var animationTimer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
self.animationTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.animate), userInfo: nil, repeats: true)
}
注意点
Timerが不要となったタイミング(testViewが非表示になった場合等)で、下記のようにinvalidateを呼んでTimerを無効化しておくとよいでしょう。invalidateを行わずにTimer.scheduledTimerを繰り返しセットし続けたりすると、クラッシュの原因となるため注意してください。
self.animationTimer?.invalidate()
例えば独自のUIViewにTimerを持たせていた場合、下記のようにすることでViewが非表示になるタイミングでTimerをオフにできます。
override func willMove(toWindow newWindow: UIWindow?) {
super.willMove(toWindow: newWindow)
if (newWindow == nil) {
self.animationTimer?.invalidate()
}
}