0

I have a few views in an HStack which gives me a view like this

SwiftUI HStack

There are 3 images and 2 Text views in here

My goal is to support graceful dynamic text / font scaling for larger text sizes, that is scaling the images and the text views.

This works for the most part:

HStack SwiftUI Dynamic Text Accessibility HStack

HStack SwiftUI Dynamic Text Accessibility

My issue arises on really large sizes and with the text, the text itself seems break because it is within an HStack

HStack SwiftUI Dynamic font large text

What I desire is for the 19.5 to be in 1 line and the the 20 to be on another line rather than the 19.5 breaking - is this possible ?

I've tried things like applying .lineLimit() of 1 and nil to the text as I saw in some answers but that didn't work.

I've also tried applying .fixedSize(horizontal: false, vertical: true) to the text to no avail.

I use @ScaledMetric outlined in this answer to scale the image.

Happy to share any code, however, it is just a basic HStack with 3 image views and two text views.

2
  • Did you try Text("19.5") + Text("/") + Text("20") instead of HStack? Commented Feb 28, 2024 at 6:51
  • 1
    @lazarevzubov - I did give this a shot but it did not give me the desired result. Commented Feb 28, 2024 at 7:30

1 Answer 1

2

Try applying . minimumScaleFactor in combination with .scaledToFit to the HStack with the Text elements:

private var target: some View {
    Image(systemName: "target")
        .resizable()
        .scaledToFit()
        .foregroundStyle(.red)
        .frame(width: 40, height: 40)
}

var body: some View {
    HStack(spacing: 0) {
        target
        target
        target
        HStack(spacing: 0) {
            Text("19.5")
                .foregroundStyle(.yellow)
            Text("/")
                .foregroundStyle(.white)
            Text("20")
                .foregroundStyle(.white)
        }
        .padding(.leading, 10)
        .font(.largeTitle)
        .minimumScaleFactor(0.1)
        .scaledToFit()
    }
    .frame(maxWidth: .infinity, maxHeight: .infinity)
    .background(.black)
}

Screenshot

Sign up to request clarification or add additional context in comments.

2 Comments

This solution works really well for the most part. The only thing I notice is that at a certain point, the image keeps scaling and then the text starts shrinking. So I applied your minimumScaleFactor and .scaledToFit to the outer HStack which almost gives the desirable result. The only minor issue now is that at the max size - the 19.5 becomes slightly smaller than the / and 20. Not sure if there is a simple way to ensure they are always the same size.
@ShawnFrank Pleased to hear you're getting nearer to a solution. I would suggest keeping the scaledToFit on the inner HStack and then find another way to resolve the issue of the image scaling. You could submit a new post if you need help (with a minimal reproducible example to demonstrate the issue).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.