Bartłomiej Semańczyk
Bartłomiej Semańczyk

Reputation: 61774

How to prevent Text from spreading VStack?

This is what I have in code:

VStack(spacing: 2) {
    Text("23:11:45") or "23:11"
        .foregroundColor(Color(uiColor: mode.underlayBackgroundColor))
        .font(.liberationMonoRegular(withSize: 46))
        .multilineTextAlignment(.center)
        .scaledToFill()
        .minimumScaleFactor(0.5)
    ProgressView(value: progress, total: 1)
        .tint(Color(uiColor: mode.underlayBackgroundColor))
        .foregroundColor(Color(uiColor: mode.underlayBackgroundColor)
        .opacity(0.3))
}
.fixedSize()
.background(.blue)

VStack is wrapped into:

ScrollView {
}
.background(.red)
.frame(maxWidth: .infinity)

here is version for "23:11:45"

enter image description here

here is version for "23:11"

enter image description here

As you can see the Text with 23:11:45 String extends VStack although it should change the scale of the font. What to do to make it working? Maximum width is 100% - padding for both sides.

Upvotes: 1

Views: 253

Answers (1)

rob mayoff
rob mayoff

Reputation: 385500

Your use of fixedSize propagates down and tells the Text not to scale down.

Compare:

text laid out with and without the fixedSize modifier within a frame(width: 50). With the fixedSize modifier, the Text spills out wider than the 50-point width. Without the fixedSize modifier, the Text shrinks to try to fit within the 50-point width.

Here's the code that generated that image:

    VStack(spacing: 10) {
        Text("with fixedSize:")

        VStack {
            Text("Hello world")
            Text("Hello world")
                .font(Font.custom("Palatino", fixedSize: 46))
        }
        .fixedSize()
        .minimumScaleFactor(0.5)
        .frame(width: 50)
        .background(Color.black.opacity(0.2))

        Spacer().frame(height: 40)

        Text("without fixedSize:")

        VStack {
            Text("Hello world")
            Text("Hello world")
                .font(Font.custom("Palatino", fixedSize: 46))
        }
        .minimumScaleFactor(0.5)
        .frame(width: 50)
        .background(Color.black.opacity(0.2))
    }
    .lineLimit(1)

It doesn't matter if the fixedSize comes before or after the minimumScaleFactor. It does matter if it's before or after the frame.

Upvotes: 1

Related Questions