1

In SwiftUI, I'm trying to use minimumScaleFactor to adapt Text size automatically. It looks like it has curious behaviors. For ex, it works with usual characters but fails with accented characters. I'm searching for a solution without arbitrary ratio and that works with all fonts.

Here is a simplified example showing the actual behavior vs the expected behavior.

What am I doing wrong?

import SwiftUI

struct TestScaleView: View {
    let text: String
    var body: some View {
        GeometryReader { geo in
            Text(self.text)
                .font(.system(size: 1000))
                .minimumScaleFactor(.leastNonzeroMagnitude)
                .lineLimit(1)
                .frame(width: geo.size.width, height: geo.size.height)
        }
    }
}

struct TestNoScaleView: View {
    let text: String
    var fontSize: CGFloat
    var body: some View {
        GeometryReader { geo in
            Text(self.text)
                .font(.system(size: self.fontSize))
                .lineLimit(1)
                .frame(width: geo.size.width, height: geo.size.height)
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            // WHAT HAPPENS
            TestScaleView(text: "This shall scale perfectly!")
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("This is acceptable but not perfect")
            TestScaleView(text: "This shall scale perfectly with special characters like é or @!")
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("Ouch.")
            TestScaleView(text: "Small")
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("Not working well, right?")

            // WHAT IS EXPECTED
            TestNoScaleView(text: "This shall scale perfectly!", fontSize: 46)
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("Adjusted manually")
            TestNoScaleView(text: "This shall scale perfectly with special characters like é or @!",
                            fontSize: 18)
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("Adjusted manually")
            TestNoScaleView(text: "Small",
                            fontSize: 94)
                .previewLayout(.fixed(width: 500, height: 70))
                .previewDisplayName("Adjusted manually")
        }
    }
}

SwiftUI preview

Spi
  • 436
  • 4
  • 16

2 Answers2

0

I followed this order

  • lineLimit
  • font
  • minimumScaleFactor

seems works well.

VStack {
    Text("This shall scale perfectly!")
        .lineLimit(1)
        .font(.system(size: 100))
        .minimumScaleFactor(.leastNonzeroMagnitude)

    Divider()
    Text("This may okay to be truncated from the middle, I am adding more text!!")
        .truncationMode(.middle)
        .lineLimit(1)
        .font(.system(size: 40))
        .minimumScaleFactor(0.5)

    Divider()
    Text("This shall scale perfectly with special characters like é or @!")
        .lineLimit(1)
        .font(.system(size: 38))
        .minimumScaleFactor(.leastNonzeroMagnitude)

    Divider()
    Text("Small")
        .lineLimit(1)
        .font(.system(size: 60))
        .minimumScaleFactor(0.1)           
}

Result

By the way, if you want to force break this scaling with a font size like 1000, you probably can achieve :)

Enes Karaosman
  • 1,889
  • 20
  • 27
  • The ordering doesn't fix my example. I still don't understand why it doesn't scale down from 1000 (or whatever) and why if you remove accented characters, it suddenly resize differently. You can try on your example as well. Ex: try to modify the first text - even with size set to 100, if you add just one accented character, it breaks the scaling... – Spi May 01 '20 at 12:00
  • now I tried again to force break it with special characters, we miss a couple character (like you said) from the end (Seems a small bug in SwiftUI). But also it can be fixed by adding padding – Enes Karaosman May 01 '20 at 13:44
0

I my case, don't set minimumScaleFactor too low

if your font size is 100 the minimumScaleFactor should be 0.01

I used to set it to 0.00001 and the wired problem occur

saranpol
  • 2,177
  • 1
  • 23
  • 22