content【Swift】AutoLayoutのPriorityを使ってアニメーション風のView制御をするiOSAutoLayoutSwiftAutoLayoutに関する記事は星の数ほどあるので今更感がありますが、自らの確認も兼ねて投稿します。画面の上下に適当な大きさのUIViewを2つ配置し、下側のViewに高さの制約をつけてOutlet接続しました。NSLayoutConstraint!touchesMoved(_:with:)をオーバーライドして、多少の処理を追加します。処理内容は、画面上のタッチイベントのY座標の変化量に合わせて画面下部のViewの高さの制約を変えています。これで画面上で指を動かすと、動きに合わせて下側のViewが伸び縮みするようになりました。本記事の趣旨ではないので特に深堀りはしません。Viewに追従するImageView下部のViewに合わせて動くImageViewを配置します。GoogleMapアプリで使われているフローティングアクションボタンのようなものです。配置した結果がこのような感じ。フローティングボタンにしては主張が激しい気もしますが、今の所無視します。画像素材はいらすとや様から拝借しました。ImageViewの制約はX座標が画面中央、またImageViewBottomが下部のViewTopから10ptの位置となっています。この10ptの制約のおかげで、下部のViewが伸び縮みした際に追従するようになります。このままではImageViewの高さや上部に対してレイアウト上の制約が存在しないため、上部のViewをImageViewが突き抜けてしまいます。View同士の重なり順を変更して、ImageViewが上部のViewの下に隠れるようにしてもいいですが、AutoLayoutで解決することが目的なので実装を進めます。Priorityを使ったImageView制御ImageViewの上端が上部のViewの下端に達した際の動作を2パターン作ってみます。1.ImageViewが縮小するImageViewに対して制約を追加します。制約の内容は、上部のViewBottomからImageViewTopの距離が0pt以上としました。-の値を許容しないのでImageViewが上部のViewまで突き抜けることはなくなります。ImageViewに対して高さの制約を設けていないため、実行するとImageViewが拡縮します。このままでは縦方向の制約2種が衝突してしまうという問題があるので次のパターンで同時に解説します。2.ImageViewが上端に留まるパターン1ではImageViewに高さの制約がなかったため拡縮しました。次は、ImageViewのサイズを固定してその上にViewが重なるように作ってみます。AutoLayoutの制約には各々にPriority(優先度)という設定項目があり、制約同士が衝突した場合にPriorityの高い順に優先して処理されます。パターン2を実現するために、以下のような優先順位をつけました。1.ImageViewの高さ(ImageViewのサイズを固定することを最優先とする)2.ImageViewと上部Viewの距離(ImageViewが上部Viewまで突き抜けないことを次に優先する)3.ImageViewと下部Viewの距離(上記2つの制約が満たされている場合動作する)Priorityのつけ方は何通りかありますが、インスペクタで制約を表示させて右端のEditボタンから編集するのが簡単かと思います。2のPriorityを999、3のPriorityを998に設定しました。Priorityで設定してみます。PriorityこれはUILabelやUIImage等、何らかのコンテンツを内包するViewが持つPriorityです。本記事中、Viewに追従するImageViewの項で、ImageViewの制約はX座標が画面中央、またImageViewBottomが下部のViewTopから10ptの位置となっています。書きましたが、これが例えばImageViewでなくUIViewだと、ストーリーボード上で警告が表示されます。この問題はUIViewのサイズをAutoLayoutで決定できないために引き起こされます。UILabelやUIImageViewでは表示するテキストや画像によって自動的に固有サイズが割り当てられるので、明示的にサイズを指定せずともAutoLayoutが動作するようになっています。いわれると、内包するコンテンツの小さくなりにくさ、潰れにくさ、とでもいいましょうか。この値が高ければ高いほど、もともとのコンテンツサイズを維持しようとします。ちなみにDefaultではPriorityが750で設定されています。Priorityを1000に設定します。これで以下のように設定できたので実行してみます。1.ImageViewの高さ(Priority@1000)2.ImageViewと上部Viewの距離(Priority@999)3.ImageViewと下部Viewの距離(Priority@998)ImageViewのサイズが固定され、更に上部のViewに突き抜ける事もなくなりました。終わりに今回はImageViewが縮小する、ImageViewが上端に留まるという2パターンを実装してみました。同じ要領で一つ一つ制約を重ねていけばAutoLayoutのみで記事冒頭のgifのような動きが表現できます。説明するためにPriorityに優先順位をつけましたが、制約同士が衝突しない場合は当然ながらPriorityを考慮する必要はありません。参考AppleのAutoLayoutGuidです。