Давайте определим это представление:
struct FlexibleTextView: View {
let possibleTexts: [String]
var body: some View {
GeometryReader { geometry in
Text(self.possibleTexts.last(where: { $0.size(withAttributes: [.font: UIFont.systemFont(ofSize: 17.0)]).width < geometry.size.width }) ?? self.possibleTexts[0])
.lineLimit(1)
}
}
init(_ possibleTexts: [String]) {
self.possibleTexts = possibleTexts.sorted {
$0.size(withAttributes: [.font: UIFont.systemFont(ofSize: 17.0)]).width < $1.size(withAttributes: [.font: UIFont.systemFont(ofSize: 17.0)]).width
}
}
}
Когда вы его инициализируете, возможные тексты автоматически сортируются по их фактической ширине. Он берет последний (то есть один ширина наибольшую ширину), где ширина меньше ширины контейнера, которую мы получаем из GeometryReader. Если даже первый, то есть самый маленький текст слишком большой (поэтому .last(where: { ... })
вернет ноль), мы по-прежнему будем использовать этот первый текст, но вы также можете изменить его самостоятельно на то, что захотите.
Вот интерактивный пример:
struct ContentView: View {
@State var width: CGFloat = 80
var body: some View {
VStack {
FlexibleTextView(["1\"", "1 in", "1 inch", "one inch"])
.frame(width: width, height: 17)
.border(Color.red)
Slider(value: $width, in: 10 ... 80)
}
.padding()
}
}
С помощью ползунка вы можете настроить ширину, чтобы увидеть эффект.