✍️

ビューを画面いっぱいに広げるアニメーション

2022/09/12に公開

タップして遷移する際などにこうしたアニメーション表現見受けられた気がするので、自分でちょっと考えてみたのですが、わりとすぐに実装できたので残しておきます。

モノ

実際のアニメーションです。ちなみに、ウェーブのように連続しているのは単にボタンタップを連続しているだけです。

code

次のようなコードで実現しています。ここでは貼り付けたビュー(testView)自体を拡大させるのではなく、その上に見た目同じものをサブビューとして重ね合わせて、拡大することで実現しています。testViewを拡大させても変わりありませんが、ややこしさを避けるのもあって、このようにしました。

import UIKit
import Foundation

class ViewController: UIViewController {
    
    @IBOutlet weak var testView: UIView!
    @IBOutlet weak var button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = "UIKitTest"
        print(testLabel.frame)
        
        button
            .addAction(
                UIAction(handler: { [weak self] _ in
                    self?.animate()
                }),
                for: .touchUpInside
            )
    }
    
    //実際のアニメーション
    func animate() {
        //サブビューの生成、サイズを合わせる
        let animatedView = UIView(frame: testView.bounds)
        //中心を揃える(重ねる)
        animatedView.center = testView.center
        //ビューに載せる(挿下できるようにUIButtonの直下にinsert)
        self.view.insertSubview(animatedView, belowSubview: button)
        
	//検証のための色付け
        animatedView.backgroundColor = testView.backgroundColor
        
        //実際のアニメーション
        UIView.animate(withDuration: 2.0, animations: { [self] in
            //サイズは画面いっぱいに広げる
            animatedView.bounds.size = self.view.bounds.size
            //サブビューの中心を画面の中心に位置に動かす
            animatedView.center = self.view.center
            
	    //検証のための色付け
            animatedView.backgroundColor = .cyan
        }) { done in
            
	    UIView.animate(withDuration: 1.0) {
                //必要であれば完了時にビューの階層から取り除く操作
                animatedView.removeFromSuperview()
            }
        }
    }
}

要点としては、位置とサイズです。位置に関しては、ビューの中心から画面の中心へ変化するということ、サイズに関してはビューのサイズから画面のサイズに変化するということ、この2点となります。

とくに位置に関して実際に試してみるとわかりますが、ビューの中心を起点にしなければ画面の左上がx,yの座標の起点であるため、拡大するような表現にはならなくなってしまいます。

所感

意外とすんなりと思いつくことができました。たとえば、コレクションビューのセルをタップした際に同様の表現を行うと考えると、タップしたセルのsizeと中心を取得してサブビューを載せてといった形にすれば良さそうです。ウェーブのように連続して動作させるのは、タイマーでリピートさせたらいいのかな?波打つような表現なども興味があります。

Discussion