UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Vertical align icon of Label

Forums > SwiftUI

Is is possible to control the vertical alignment of the icon of a Label? The default seems to be .firstTextBaseline, but i need . center. I know its possible to build a custom LabelStyle, but then you loose some built in layout behaviour.

2      

Do you mean horizontally next to the text. In the Xcode 12 beta 5. The the centre of icon is align to the centre of text.

2      

But only the the first line of text.

This...

struct ContentView: View {
    var body: some View {
        Label {
            VStack {
                Text("Foo")
                Text("Bar")
            }
        } icon: {
            Image(systemName: "paperplane.fill") 
        }
    }
}

...produces:

image

Any idea how to align the icon to the vertical center of the whole VStack?

2      

The only way I get to do it is

struct CustomLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack {
            configuration.icon
            configuration.title
        }
    }
}

then add

struct ContentView: View {
    var body: some View {
        Label {
            VStack {
                Text("Foo")
                Text("Bar")
            }
        } icon: {
            Image(systemName: "paperplane.fill") 
        }
        .labelStyle(CustomLabelStyle())
    }
}

and this give icon in the middle of the VStack.

I can not see the layout behaviour you lose! It still work with Dynamic Text Format.

2      

Thanks Nigel - your solution solves the vertical aligment - but creates another layout problem:

image

The text of different cells in not aligned anymore. When i use the default label style it renders as:

image

I need both: the icon in the vertical center of the text VStack and the text of different cells horizontal aligned.

2      

OK add this to LabelStyle

struct CustomLabelStyle: LabelStyle {
  @Environment(\.sizeCategory) var size

  func makeBody(configuration: Configuration) -> some View {
    HStack {
        if size >= .accessibilityMedium {
            configuration.icon
                .frame(width: 80)
        } else {
            configuration.icon
                .frame(width: 30)
        }
        configuration.title
    }
  }
}

You might want to play around with the frame width but it seem to work.

2      

That will do it ... would be nice to solve it without hard coded sizes.

That is propably the best solution for now - maybe they add a vertical alignment argument in the future. If i find a better solution, i will post it here.

2      

I managed to achieve vertical centre alignment while preserving the default horizontal alignment by tweaking Label's vertical alignment guides in a LabelStyle:

struct CentreAlignedLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        Label {
            configuration.title
                .alignmentGuide(.firstTextBaseline) {
                    $0[VerticalAlignment.center]
                }
        } icon: {
            configuration.icon
                .alignmentGuide(.firstTextBaseline) {
                    $0[VerticalAlignment.center]
                }
        }
    }
}

Essentially the alignmentGuide modifiers tell Label to use values from the center alignment for its default alignment of firstTextBaseline. So although conceptually it's still aligning according to firstTextBaseline, the actual visual effect becomes that of center.

3      

@erithacus-rubecula-z

Your solution looks promising, but for me it does not work. Can you post an full example?

2      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.