iosswiftstringswiftui

SwiftUI: How can I limit a string to be displayed as one line, and support automatic scaling to a specified ratio, sliding to view the full text


How can I limit a string to be displayed as one line, and support automatic scaling to a specified ratio, and support sliding to view the full text without being truncated in SwiftUI

problem

(1).minimumScaleFactor(0.3) // doesn't work

(2)text is being truncated // hope it won't be truncated

Here is the code


import SwiftUI

struct ContentView: View {

@State private var text = "In the scrollview of SwiftUI, I have a very long string, which is limited to one line, and automatically scaled to the specified ratio, and can slide to display the full content without being truncated"

var body: some View {
    VStack {
        ScrollView(.horizontal){
            Text(text)
                .font(.system(size: 80))
                .lineLimit(1)
                .minimumScaleFactor(0.3)
        }
        Text("this is another text")
    }
}

}


simulator image:

enter image description here

The string to be displayed as one line, and support automatic scaling to a specified ratio, and support sliding to view the full text without being truncated in SwiftUI.


Solution

  • EDIT: revised to use ViewThatFits and a hidden footprint.


    So if I understand correctly...

    The problem you were having in your example is that the ScrollView disables the scaling.

    One way to solve is to use a hidden version of the text to establish a footprint:

    By using ViewThatFits, the text is only wrapped with a ScrollView if it needs to be. This prevents a short text from moving when it is "pushed", because there will be no ScrollView around it.

    private let longText = "In the scrollview of SwiftUI, I have a very long string, which is limited to one line, and automatically scaled to the specified ratio, and can slide to display the full content without being truncated"
    
    private func formattedText(key: String) -> some View {
        Text(LocalizedStringKey(key))
            .font(.system(size: 80))
            .lineLimit(1)
            .minimumScaleFactor(0.3)
    }
    
    private func textLine(_ key: String) -> some View {
        formattedText(key: key)
            .hidden()
            .overlay(
                ViewThatFits(in: .horizontal) {
                    formattedText(key: key)
                    ScrollView(.horizontal) {
                        formattedText(key: key)
                    }
                }
            )
    }
    
    var body: some View {
        VStack(alignment: .leading) {
            textLine(longText)
            textLine("this is another text")
        }
    }
    

    text line