HStack等の alignment 指定は、直感的に理解できたのですが、alignmentGuide については、今一つわかっていなかったので、改めて考えてみました。
alignmentGuide は、あくまで Guide
当たり前ですが、alignmentGuide だけで、何かをレイアウトすることはありません。
alignment を要求されたときに、その指定位置としてどこを指定するかということを設定します。
HStack の例
テキストが横方向に並んでいるとします。
var body: some View {
HStack {
Text("Hello, World!")
.font(.largeTitle)
Text("Hello again!")
.font(.footnote)
}
}
表示は、各行の中央に揃えられて、以下のようになります。
このときに、各行の下辺で揃えたいとすると、HStack に alignment: .bottom を指定します。
Stackで、Top/Center/Bottomで揃えると指定すると、各要素(この場合はText)に対して、指定位置がどの位置かをStackから問い合わせが来ます。Stackは、そこから返された値で配置を行うというような動作になります。
このときの各要素から返す値を変更するための modifier が、alignmentGuide です。
alignmentGuide で揃え位置を変更
先の例で、”Hello again!”については、文字列の上辺を揃え位置としたいときは、以下のようにして、.bottom 指定に対して、自分の.top 位置を返します。
Text("Hello again!")
.font(.footnote)
.alignmentGuide(.bottom) { (d) -> CGFloat in return d[.top]}
すると、HStack は、.bottom に合わせようとしているのですが、以下のようになります。
注意点
alignmentGuide は、あくまで、聞かれた alignment に対して、回答するためのものなので、alignmentGuide を記述しても相応する alignment を要求されないと意味ないです。
例えば、以下のようなコード
HStack(alignment: .bottom) {
Text("Hello, World!")
.font(.largeTitle)
Text("Hello again!")
.font(.footnote)
.alignmentGuide(.leading) { (d) -> CGFloat in return d[.trailing]}
}
}
2つめの Text の alignmentGuide で .leading に対して、.trailing を返すようにしているのですが、上位ビューから、.leading での alignment を要求されないので、レイアウトに影響を与えません。
まとめ:Stack の alignment と alignmentGuide
Stack の alignment は、自分の包含するビューのレイアウトを指定することができます。そのときに、子ビューが指定位置に自分のどこに合わせるかを alignmentGuide で指定することができるということです。
これまでは、InterfaceBuilder で要素感に制約をつけることで管理していたレイアウトを、Stack というグループに分解し、そのグループ内での位置関係で制約するということになります。グループを超えて関係づけることはこのままではできませんが、凝ったレイアウトでなければ、素早くわかりやすいレイアウトを作れる仕組みに思えます。
Sponsor Link