例如,如果我的UI需要以人类可读的形式显示长度Measurement
,则它可能要从以下一种格式中选择以显示一英寸:
到目前为止,我已经尝试过:
truncationMode(_:)
:仅接受位置参数,没有自定义截断选项GeometryReader
:告诉我什么空间可用(超级有用!),但我看不到如何动态选择动态大小的子视图,似乎已针对生成固定大小的子视图或溢出进行了优化职位当我尝试找到另一个可能已解决此问题的应用程序时,似乎它们都根据方向或其他尺寸变化重新排列了布局。我希望继续在HStack
个视图中保留一个Text
个适合该空间的视图,以防止所有重要信息在可能的情况下被截断。
答案 0 :(得分:1)
让我们定义这个视图:
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: { ... })
将返回nil),我们仍将使用该第一个文本,但是您也可以自己更改为所需的文本。
这是一个交互式示例:
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()
}
}
使用滑块,您可以调节宽度以查看效果。