[SwiftUI] やっと alignmentGuideがわかってきた

SwiftUI

     

TAGS:

⌛️ < 1 min.

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使用例

注意点

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 というグループに分解し、そのグループ内での位置関係で制約するということになります。グループを超えて関係づけることはこのままではできませんが、凝ったレイアウトでなければ、素早くわかりやすいレイアウトを作れる仕組みに思えます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です