[Autolayout] サンプルケース - 親ビューの下半分に子ビューを配置 (2) アニメーション

2015年6月12日金曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

前回のやつにアニメーションを加えてみる。子ビューが下からシュッと出てくるやつ。

これは制約を使えば簡単。子ビューの上のラインを画面下端から、最終位置(この場合親ビューのCenterY)まで引き上げてやれば良い。
まず子ビューの初期位置を最終下端で作る。
let v1c = NSLayoutConstraint(item: tableView, attribute: .Top, relatedBy: .Equal,
     toItem: parentView, attribute: .CenterY, multiplier: 1.0, constant: parentView.frame.size.height)

一旦 parentView.layoutIfNeeded()で初期描画させた後、アニメーションのコードを走らせる。
v1c.constant = 0.0
        UIView.animateWithDuration(0.5) {
            parentView.layoutIfNeeded()
        }

こうすると子ビューの上の制約の値(constraint)が下端(parentView.frame.size.height)から 0.0へアニメーションしながら変化する。

なおこのままだと制約のワーニングが出る。
2015-06-11 08:10:18.938 LKMenu_Example[89282:6908924] Unable to simultaneously satisfy constraints.
 Probably at least one of the constraints in the following list is one you don't want.
 Try this: (1) look at each constraint and try to figure out which you don't expect; 
(2) find the code that added the unwanted constraint or constraints and fix it.
 (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer
 to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "",
    "",
    ""
)
  :

これは子ビューの上の制約(v1c)と下の制約(v2c)の値が初期状態では等しくなる(逆転する?)ため。こんな時は優先順位(priority)をつけてやればいい。
let v2c = NSLayoutConstraint(item: tableView, attribute: .Bottom, relatedBy: .Equal,
      toItem: parentView, attribute: .Bottom, multiplier: 1.0, constant: 0.0)
        v2c.priority = 750   // 追加
        parentView.addConstraint(v2c)
親ビューに制約を追加する前につけるのを忘れずに。これでワーニングが消える。priorityは大きい方が優先順位が高い。IBでプロパティ欄を見ると 1000(Required), 750(High), 250(Low)となっている。
デフォルト値は 1000(最大値も 1000)。


最終的なコード。
parentView.addSubview(tableView)

        tableView.setTranslatesAutoresizingMaskIntoConstraints(false)
        
        let h1c = NSLayoutConstraint(item: tableView, attribute: .Left, relatedBy: .Equal,
            toItem: parentView, attribute: .Left, multiplier: 1.0, constant: 0.0)
        parentView.addConstraint(h1c)
        let h2c = NSLayoutConstraint(item: tableView, attribute: .Right, relatedBy: .Equal,
            toItem: parentView, attribute: .Right, multiplier: 1.0, constant: 0.0)
        parentView.addConstraint(h2c)
        
        let v1c = NSLayoutConstraint(item: tableView, attribute: .Top, relatedBy: .Equal,
            toItem: parentView, attribute: .CenterY, multiplier: 1.0, constant: parentView.frame.size.height)
        parentView.addConstraint(v1c)
        let v2c = NSLayoutConstraint(item: tableView, attribute: .Bottom, relatedBy: .Equal,
            toItem: parentView, attribute: .Bottom, multiplier: 1.0, constant: 0.0)
        v2c.priority = 750
        parentView.addConstraint(v2c)
        parentView.layoutIfNeeded()
        
        v1c.constant = 0.0
        UIView.animateWithDuration(0.5) {
            parentView.layoutIfNeeded()
        }

Autolayoutはコツがわかってくると楽しい。


(おまけ)animateWithDuration:usingSpringWithDamping: を使えばアニメーションにバネ効果(バウンス効果っぽい)をつけられる。
UIView.animateWithDuration(0.5, delay: 0.0, usingSpringWithDamping: 0.7,
            initialSpringVelocity: 0.0, options: UIViewAnimationOptions.CurveEaseInOut,
            animations: { () -> Void in
            parentView.layoutIfNeeded()
        }) { (Bool) -> Void in
        }

Responses

Leave a Response

人気の投稿(過去 30日間)