Chapter 03無料公開

スクロールが止まる制約の貼り方(2)

崎山圭
崎山圭
2021.05.16に更新

GreenViewがBlueViewの位置で止まるようにする

GreenViewの制約を以下のようにします。

  • Vertical CentersPriorityをHigh(750)にする
  • TopBlueViewTopに合わせてRelationGreater Than or Equalにする

これによって全体の動きが最初の図のようにようになります。

考え方

以上なのですが、これらのパラメータを見慣れない方もいるでしょうから簡単な解説と設定箇所の説明をします。

制約のPriorityRelation

Priority

制約のPriorityとは、制約のコンフリクトが起きた時にその数値が高い方だけが反映されるパラメータです。
デフォルトではRequired(1000)になっており、Required(1000)同士の制約がコンフリクトを起こすとエラーとなります。
今回はGreenViewのy座標を決める制約であるVertical CentersPriorityを下げています。
Priorityは以下の図のように右側の設定箇所で数値を入れることで変更できます。

GreenViewの制約のPriority

Relation

制約のRelationとは、ふたつのViewをつなげる制約の関係を表すパラメータです。
Equal, Greater Than or Equal, Less Than or Equalの3つから選ぶことができ、デフォルトではEqualとなっています。
今回はGreenViewBlueViewのy座標を決める制約であるTop同士のRelationGreater Than or Equalとしています。
Greater Than or Equalの場合、GreenViewTopが、BlueViewTopより下にあれば良いということになります。(UIKitのy座標は下にいくほど高くなります)
Relationは以下の図のように右側の設定箇所で数値を入れることで変更できます。

GreenViewの制約のPriority

制約の組み合わせ

Priorityを下げてRelationGreater Than or Equalにするとなぜスクロールが途中で止まるのか説明します。

GreenViewの高さに関する制約だけ抜き出した図が以下の通りです。
PriorityをHigh(750)にした制約を1としてオレンジ色の矢印で、RelationGreater Than or Equalにした制約を2として紫の矢印で表しています。

kaisetsu01

ここでRedViewをスクロールさせていくと以下のようになります。
まだこの段階では制約の状況に変わりありません。

kaisetsu02

さらにRedViewをスクロールさせていくといずれGreenViewBlueViewと同じ高さのところまできます。
ここにくると2の制約が縦向きの矢印では書けないため横向きにしています。
Greater Than or Equalですが、現在は同じ位置にあるため、実質制約のRelationEqualと同じ状態です。

kaisetsu03

さらにRedViewをスクロールさせていくとRedViewは上にスクロールしていきますが、GreenView2の制約があるためこれ以上スクロールすることができません。
本来であればここで制約エラーとなるのですが、1Priorityが低いため、2の制約のみが反映されます。
結果、GreenViewはスクロールがBlueViewの位置で止まるという動きが制約のみで実現できました。

kaisetsu03

まとめ

制約のPriorityRelationの仕組みを組み合わせることで、途中でスクロールが止まる動きを実現させました。
考え方は以下の通りです。

  1. 動きを連動させたいUIViewを用意して位置を決める制約のPriorityを下げる(今回の場合RedView, GreenView)
  2. 動きを制限するためのUIViewを用意する(今回の場合BlueView)
  3. 動きを連動させたいUIView(今回の場合RedView)と動きを制限するためのUIView(今回の場合Blueiew)の制約を貼りRelationGreater Than or EqualLess Than or Equalにする(今回の場合RedView, Blueiew)

同じ考え方で「最終的にできあがるもの」の動きがほぼ実現できます。

ここまでのstoryboardがこちらです。