【Swift】Pin制約の使い方。部品と部品の最短距離の制約を追加する。(Swift 2.1、XCode 7.2)

2020年6月16日

Pin制約とは

前回の記事で複数部品を選択したAuto Layout(以下、オートレイアウト)について説明した。⇒「記事

前回は「部品の左端から他の部品の左端まで」、「部品の右端から他の部品の右端まで」など、同じ端同士の距離の制約について説明した。

Leading Edgesの例

今回は「部品の左端から他の部品の右端まで」、「部品の左端から画面の右端まで」など、逆の端同士、いわゆる部品間の最短距離の制約について説明する。これをPin制約という。

画面端からの距離、部品間の距離

 

検証するために、いつも通りデバイス画面にラベルを追加する。

今回は部品間の距離が把握しやすいようにラベルの外見を変更しておこう。ラベルをクリックしたあとにアトリビュートインスペクタボタン(下図黄緑枠)を押す。すると設定画面が表示されるので、Colorを白色、Backgroundを青色、Fontサイズを30に変更した。

ラベルをデバイス画面に配置する

 

配置したラベルを常に左上隅から近いところに表示したい場合について考える。

例えば、下図のように、部品をクリックしたあとに赤枠のalignボタンから「Horizontally in Container -58」、「Vertically in Container -229」の制約を追加した場合、縦画面で表示した場合は画面左上に表示されるが、端末を倒して横画面にした場合はどうなるか。

中心からの距離で部品を配置

 

以下の動画のように、横画面にした段階でラベルはいなくなる。

 

なぜなら、追加した制約は画面の中心からの距離を指定するものなので、横画面の中心から同じ距離の場所が画面外になってしまうためである。

横画面にするとラベルが画面の外にいってしまう。

画面端と部品の距離の制約を追加する

「iPadでもiPhoneでも、縦画面でも横画面でも、画面端の近くに部品を表示したい。」そんなときにPin制約を使う。

ラベルをクリックしたあとに下図青枠のPinボタンを押す。吹き出しの設定画面で、赤枠内の2つのi_markマークをクリックして「Add 2 Constraints」ボタンを押す。これで「画面左端からラベル左端までの距離」と「画面上端からのラベル上端までの距離」が制約として追加される。

Pinの設定

 

上図黄緑枠の「Constrain to margins」は、画面左右端の余白部分を考慮するかどうかの設定である。これにチェックを入れると画面左右に20pxの余白が入る。

今回の例では「Constrain to margins」にチェックを入れたので、画面左端の余白20pxのあとに22pxの距離をとることになり、実際は42ピクセルの距離になるということだ。

Constrain to marginsの例

 

以下は制約を追加したあとのプレイ動画。縦画面でも横画面でもラベルは常に画面左上に表示されるようになった。

 

ちなみに、あとから余白の考慮が不要になった場合は、制約を選択したあとにアトリビュートインスペクタボタン(黄緑枠)を押して、Second Itemの中の「Relative to margin」のチェックを外すと余白を考慮しない設定に変更される。

制約に含めた左右余白を解除する

 

上からの距離と下からの距離の制約を追加した場合

「画面上端から部品までの距離」と「画面左端から部品までの距離」は問題なく追加できた。要するに、L字方向の距離の制約は問題なく追加できる。

では、「画面上端から部品までの距離」と「画面下端から部品までの距離」などの部品を挟むような制約を追加した場合はどうなるか。試してみよう。

下図のようにラベルを追加したあと青枠のPinボタンを押して設定画面を開く。黄緑枠の2つのi_markボタンをクリックしたあとに「Add 2 Constraints」ボタンを押して制約を追加する。水平方向の位置の制約はいつもの手順で「Horizontally in Container 0」を追加する。

上と下の距離の制約を追加する

 

端末を倒して横画面にしてみよう。以下は実際のプレイ動画。ラベルが画面上から消えた。

 

端末を倒したときに以下のメッセージが出力された。

 

横画面にすると下図のように部品の位置が定まらなくなるため発生したエラーである。

ラベルの位置が定まらない

 

左からの距離と右からの距離の制約を追加した場合

では、今度は「画面左端から部品までの距離」と「画面右端から部品までの距離」を追加した場合はどうなるか試してみよう。

先ほどと同じようにラベルを追加したあと青枠のPinボタンを押して設定画面を開く。黄緑枠の2つのi_markボタンをクリックしたあとに「Add 2 Constraints」ボタンを押して制約を追加する。垂直方向の位置の制約はいつもの手順で「Vertically in Container 0」を追加する。

画面左と右からの距離の制約を追加する

 

端末を倒して横画面にしてみよう。以下は実際のプレイ動画。エラーは発生せずにラベルが横に引き延ばされた。

 

横画面にすると画面端から部品端までの距離が下図のようになる。ラベルのサイズの制約は追加してないので、制約に合うようにラベルが引き延ばされたということだ。これは入力ボックスなど、画面のサイズに合わせてサイズを伸縮させたいときに使えそうだ。

縦画面と横画面の違い

 

つまり、上下、左右などの一直線のPin制約を追加するときは、画面サイズが変わったときに上図で書いた矢印イメージの終端が交わらないように設計する必要があるということである。

 

部品と部品の距離の制約を追加する

Pin制約は画面端からの距離だけではなく、部品と部品の間の距離も設定できる。

例えば、下図のようにもう一つのラベルをデバイス画面に追加したあと、Pin設定画面から下図赤枠をクリックする。すると距離を設定できる部品の一覧が表示されるので、「ラベル1」にチェックが入っていることを確認する。

i_markマークをクリック、「Add 1 Constraints」ボタンで制約を追加すると、

部品と部品の間の距離の制約を追加する

 

ラベル2の垂直方向の制約に、ラベル2の上端からラベル1の下端までの距離が追加される。

部品間の距離の設定を追加したあと

 

部品間のPin制約を追加したいときに、対象の部品が追加したい方向に無いときは追加できないので注意すること。

例えば、下図のようにラベル2を追加したが、ラベル2の真っ直ぐ上にはラベル1が存在しない。そのため、pin設定画面から下図赤枠をクリックしても、距離を設定できる部品の一覧にラベル1は現れない。

部品間の制約をつける前

次回はPin制約の続きで、部品のサイズに関する制約について説明する。