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:
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.
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:
ScrollView
, so it will be truncated if it is very long and cannot be scaled any further.ViewThatFits
is used to show the text without a ScrollView
(if it fits) or with a ScrollView
(if it doesn't).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")
}
}