以牺牲 HStack 中相邻的 Divider 控件为代价,将 Text 控件的优先级设置得尽可能宽
Prioritising a Text control to be as wide as possible at the expense of an adjacent Divider control in a HStack
我有一个视图由 HStack 中的多个 UI 元素组成:
- 时间
- 图标
- 总结
- 分隔线
- 价值
我希望 1)、2) 和 5) 占用的空间不超过 space,即我不需要干预。
对于 3) 和 4) 我希望摘要尽可能多地占用 space,但要牺牲后面的分隔线。如果这意味着可以出现 none 或最小数量的分隔符,那就这样吧。然而,尽管我尽了最大的努力,摘要似乎只占用了一定数量的 space,导致其内容在多行中 运行 以确保分隔符始终出现。给它一个 layoutPriority 略有帮助。
我不想给它一个 minWidth,因为我希望根据内容动态安排宽度的分布。
代码如下:
HStack {
// MARK: Time
HStack {
VStack {
Spacer()
Text("9am")
Spacer()
}
}.padding(.horizontal, 4)
.padding(.vertical)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
VStack {
HStack {
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(Font.title2)
// MARK: Summary
VStack {
HStack {
Text("Humid and overcast")
.padding(.trailing, 2)
.background(Color.white)
.layoutPriority(100)
Spacer()
}
}
// MARK: Line
VStack {
Spacer()
Divider()
Spacer()
}
// MARK: Values
VStack {
Text(String(22.66))
Text("25%")
.foregroundColor(Color.black)
.background(Color.white)
}
Spacer()
}
}
}
这是它的样子:
当文本有足够的空间放在一行时,您可以将文本 运行 分到多行,只要后面的分隔线变短以容纳较长的文本即可。
固定大小在这里应该会有帮助。使用 Xcode 12.1 / iOS 14.1
测试
struct TestLongHStack: View {
var body: some View {
HStack {
// MARK: Time
HStack {
VStack {
Spacer()
Text("9am")
Spacer()
}
}.padding(.horizontal, 4)
.padding(.vertical)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
VStack {
HStack {
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(Font.title2)
// MARK: Summary
VStack {
HStack {
Text("Humid and overcast").fixedSize() // << here !!
.padding(.trailing, 2)
.background(Color.white)
.layoutPriority(100)
Spacer()
}
}
// MARK: Line
VStack {
Spacer()
Divider()
Spacer()
}
// MARK: Values
VStack {
Text(String(22.66)).bold().italic()
Text("25%").font(.footnote)
.foregroundColor(Color.black)
.background(Color.white)
}
Spacer()
}
}
}.fixedSize(horizontal: false, vertical: true)
}
}
有很多 VStack / HStack / Divider / Spacer 可以使用一些 HStack 属性进行优化。下面是完全相同的显示,布局代码少得多,并且去掉了古怪的分隔线元素:
struct TesterView: View {
var body: some View {
HStack(alignment: .center, spacing: 10) { // use alignment and spacing instead of all the VStack formatting
// MARK: Time
Text("9am")
.padding(.vertical, 20).padding(.horizontal, 5) // specifically set a padding number instead of relying on default
.background(Color.blue.opacity(0.2)
.cornerRadius(8))
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(.title2)
// MARK: Summary
Text("Humid and overcast")
.fixedSize(horizontal:true, vertical:false)
.background(Color.white)
// MARK: Line
// note: Rectangle expands to fill space just like Divider, use .frame() to control its height
// IMO relying on Divider to interpret its parent container and expand properly seems whacky and non-specific
Rectangle()
.fill(Color.black.opacity(0.2))
.padding(.horizontal, 5)
.frame(height:1)
// MARK: Values
VStack {
Text(String(22.66)).bold().italic()
Text("25%").font(.footnote)
.foregroundColor(Color.black)
.background(Color.white)
}
}
.padding(.horizontal, 20) // added HStack padding to push off screen edges
}
}
我有一个视图由 HStack 中的多个 UI 元素组成:
- 时间
- 图标
- 总结
- 分隔线
- 价值
我希望 1)、2) 和 5) 占用的空间不超过 space,即我不需要干预。
对于 3) 和 4) 我希望摘要尽可能多地占用 space,但要牺牲后面的分隔线。如果这意味着可以出现 none 或最小数量的分隔符,那就这样吧。然而,尽管我尽了最大的努力,摘要似乎只占用了一定数量的 space,导致其内容在多行中 运行 以确保分隔符始终出现。给它一个 layoutPriority 略有帮助。
我不想给它一个 minWidth,因为我希望根据内容动态安排宽度的分布。
代码如下:
HStack {
// MARK: Time
HStack {
VStack {
Spacer()
Text("9am")
Spacer()
}
}.padding(.horizontal, 4)
.padding(.vertical)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
VStack {
HStack {
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(Font.title2)
// MARK: Summary
VStack {
HStack {
Text("Humid and overcast")
.padding(.trailing, 2)
.background(Color.white)
.layoutPriority(100)
Spacer()
}
}
// MARK: Line
VStack {
Spacer()
Divider()
Spacer()
}
// MARK: Values
VStack {
Text(String(22.66))
Text("25%")
.foregroundColor(Color.black)
.background(Color.white)
}
Spacer()
}
}
}
这是它的样子:
当文本有足够的空间放在一行时,您可以将文本 运行 分到多行,只要后面的分隔线变短以容纳较长的文本即可。
固定大小在这里应该会有帮助。使用 Xcode 12.1 / iOS 14.1
测试struct TestLongHStack: View {
var body: some View {
HStack {
// MARK: Time
HStack {
VStack {
Spacer()
Text("9am")
Spacer()
}
}.padding(.horizontal, 4)
.padding(.vertical)
.background(Color.blue.opacity(0.2))
.cornerRadius(8)
VStack {
HStack {
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(Font.title2)
// MARK: Summary
VStack {
HStack {
Text("Humid and overcast").fixedSize() // << here !!
.padding(.trailing, 2)
.background(Color.white)
.layoutPriority(100)
Spacer()
}
}
// MARK: Line
VStack {
Spacer()
Divider()
Spacer()
}
// MARK: Values
VStack {
Text(String(22.66)).bold().italic()
Text("25%").font(.footnote)
.foregroundColor(Color.black)
.background(Color.white)
}
Spacer()
}
}
}.fixedSize(horizontal: false, vertical: true)
}
}
有很多 VStack / HStack / Divider / Spacer 可以使用一些 HStack 属性进行优化。下面是完全相同的显示,布局代码少得多,并且去掉了古怪的分隔线元素:
struct TesterView: View {
var body: some View {
HStack(alignment: .center, spacing: 10) { // use alignment and spacing instead of all the VStack formatting
// MARK: Time
Text("9am")
.padding(.vertical, 20).padding(.horizontal, 5) // specifically set a padding number instead of relying on default
.background(Color.blue.opacity(0.2)
.cornerRadius(8))
// MARK: Icon
Image(systemName: "cloud.drizzle.fill")
.font(.title2)
// MARK: Summary
Text("Humid and overcast")
.fixedSize(horizontal:true, vertical:false)
.background(Color.white)
// MARK: Line
// note: Rectangle expands to fill space just like Divider, use .frame() to control its height
// IMO relying on Divider to interpret its parent container and expand properly seems whacky and non-specific
Rectangle()
.fill(Color.black.opacity(0.2))
.padding(.horizontal, 5)
.frame(height:1)
// MARK: Values
VStack {
Text(String(22.66)).bold().italic()
Text("25%").font(.footnote)
.foregroundColor(Color.black)
.background(Color.white)
}
}
.padding(.horizontal, 20) // added HStack padding to push off screen edges
}
}