0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NSLayoutAnchorでのアニメーション[Swift]

Last updated at Posted at 2019-12-15

状況

Youtubeチャンネルの素材用にTinderの模擬アプリを作成する際、
NSLayoutAnchorでの制約のActiveの切り替えてアニメーションをやりたかったのですが
なかなかうまくいかなかったのでメモ。
NSLayoutAnchor: コードでAutoLayout設定できる方法の1つ。
StoryboardでいうところのAdd New Constraintsのような感覚で制約を設定できる。

やりたいこと

Tinderの模擬アプリにおいてtouchesEnded(Viewから指を離す)したら
指を離した座標によって

  • Viewを真ん中に戻す
  • ViewをVC外に移動し削除する

どちらかの挙動を選択する

対策

NSLayoutAnchor使わない

やりたいことはViewの移動なので
直接中心座標を指定してアニメーションする

let screenWidth = self.view.frame.width
let screenHeight = self.view.frame.height
        if viewCenter.x <= screenWidth/4 {
            //Viewの中心座標が左右1/4にあれば最前面のViewを消す
            UIView.animate(withDuration: 0.2, animations: {
                draggedView!.center = CGPoint(x: -screenWidth/2, y: (screenHeight+64)/2)
            }) { _ in //completion
                draggedView!.removeFromSuperview()
                self.girlsViewArray.removeLast()
            }
            
        } else if viewCenter.x >= 3*screenWidth/4 {
            //Viewの中心座標が左右1/4にあれば最前面のViewを消す
            UIView.animate(withDuration: 0.2, animations: {
                draggedView!.center = CGPoint(x: 3*screenWidth/2, y: (screenHeight+64)/2)
            }) { _ in //completion
                draggedView!.removeFromSuperview()
                self.girlsViewArray.removeLast()
            }
            
        } else {
            //中心座標に戻したいので制約を有効にする //どうやら効いてない
            UIView.animate(withDuration: 0.2) {
                draggedView!.center = CGPoint(x: screenWidth/2, y: (screenHeight+64)/2)
                draggedView!.likeView.alpha = 0
                draggedView!.nopeView.alpha = 0
            }
        }

疑問点

このアニメーションをする前のdraggedViewの初期設定で
こんな感じでNSAutoLayoutでViewの位置をガッチリ固めていたのですが
view.centerview.frameを変更したら
制約を変更(false)しなくてもViewが動いたのが疑問。
frameをハードコードしたら制約は無効になるの??
 わかりません。。

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        Array(0..<girlsViewArray.count).forEach {
            //制約
            girlsViewArray[$0].widthAnchor.constraint(equalTo: self.view.widthAnchor , constant: -2*margin).isActive = true
            girlsViewArray[$0].heightAnchor.constraint(equalTo: self.view.heightAnchor, constant: -(44+20)-2*margin).isActive = true
            //44.0(navHeight) + 20.0(statusBarHeight) + 2*10(margin)
            girlsViewArray[$0].centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
            girlsViewArray[$0].centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: (44+20)/2).isActive = true
            //44.0(navHeight) + 20.0(statusBarHeight)
        }
    }

UIKitのView表示ライフサイクルを理解する - Qiita
->この記事にあるように

  • Viewの読み込み
  • 制約の追加(AutoLayout)
  • 制約を元にViewのframeを計算(レイアウト)
  • frameの位置に描画(レンダリング)

の順番だとすれば、frameをハードコードしたら制約が無効になるのも納得がいくかも。。。

参考

iOS, AutoLayoutで簡単にできるアニメーション - Qiita
UIKitのView表示ライフサイクルを理解する - Qiita

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?