Home > Net >  SwiftUI align SF Symbol as text with a text
SwiftUI align SF Symbol as text with a text

Time:12-31

I need to display a SF Symbol (image) and a text in a view (as a title). As the text could be quite long, I want that it passes under the image for second line.

Expected result (almost!):

enter image description here

I first tried a HStack with image and text. But text doesn't go under image: Second line starts with a left 'padding' (corresponding to left image space).

So I did this code (to get previous screenshot):

HStack(alignment:.top) {
    Text(Image(systemName: "circle.hexagongrid.circle"))
        .font(.caption)
        .foregroundColor(.pink)
     
    Text("A long text as example")
        .font(.title2).bold()
        .foregroundColor(.pink)
}
.frame(width:140)

But I want to align image with center of first line. Center of image should be vertically in middle of top of A and bottom of g.

It is important that my second (and more) line passes under my image. And I don't want a bigger font for image.

CodePudding user response:

Firstly, you can remove the HStack because it is redundant. You can just replace it with brackets () to encapsulate the new Text, so you can use more modifiers like for setting the width.

The main solution is to use Result


Bonus: you can move your foregroundColor(.pink) modifier after the Texts have been combined, so you don't have to duplicate that.

CodePudding user response:

I don’t know if you can force the image to automatically be centred in all cases, but you can add a .baselineOffset() modifier to the image-in-text to shift the image upwards by a fixed amount. For example:


Text(Image(systemName: "circle.hexagongrid.circle"))
  .font(.caption)
  .foregroundColor(.pink)
  .baselineOffset(3.0)
 
Text("A long text as example")
  .font(.title2).bold()
  .foregroundColor(.pink)

Once you have hit upon the right offset amount for the default text size, you might be able to accommodate accessibility variations by making the offset size relative to a base size, e.g.

Struct MyView: View {
  @ScaledMetric(relativeTo: .title2) var baselineOffset: CGFloat = 3.0

  // and in your body…
  .baselineOffset(baselineOffset)
  • Related