具有不均匀大小元素的 SwiftUI HStack
SwiftUI HStack with uneven sized elements
Desired output
寻找一种将 HStack 拆分为不均匀元素的方法,一个占据屏幕的 1/2,另外两个占据屏幕的 1/4(见附件)。
代码:
struct MyCategoryRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 0) {
ForEach(0...2, id: \.self) { block in
ColoredBlock()
}.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)
}
}
}
所以上面的代码生成了一个 HStack,其中包含 3 个等宽的彩色块。我尝试使用 UIScreen.main.bounds.width 强制宽度,但该方法不适应方向的变化。我也试过像这样使用 GeometryReader:
GeometryReader { g in
ColoredBlock().frame(width: block == 0 ? g.size.width * 2 : g.size.width / 2)
}
但这也没有用,似乎每个ColoredBlock将占用HStack的1/3是事先决定的。
使用 layoutPriority 尝试更新:
struct MyCategoryRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 0) {
ForEach(0...2, id: \.self) { block in
ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2).layoutPriority(block == 0 ? 1.0 : 0.5)
}.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)
}
}
}
struct ColoredBlock: View {
let background: Color
var body: some View {
GeometryReader { geometry in
VStack(spacing: 0){
HStack {
Text("Some text").padding(.horizontal, 15).padding(.top, 15)
}.frame(alignment: .leading)
VStack(alignment: .leading){
Text("Some more text").font(.subheadline).fontWeight(.light)
}.padding(.vertical, 10).padding(.horizontal, 15)
}.background(self.background)
.cornerRadius(15)
}
}
}
Result:
我想你需要的是.layoutPriority。将第一个块设置为 1.0,第二个和第三个块设置为 0.5。
我最后做的是在 MyCategoryRow 中使用 GeometryReader 而不是 ColoredBlock 并将宽度传递给 ColoredBlock
HStack {
ForEach(0...2, id: \.self) { block in
ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2, width: block == 0 ? geometry.size.width / 2 : geometry.size.width / 4, height: 150.0)
}
}
这可行,但现在我发现自己必须指定一个我不希望硬编码的高度。如果谁有更好的解决方案,请告诉我!
Desired output
寻找一种将 HStack 拆分为不均匀元素的方法,一个占据屏幕的 1/2,另外两个占据屏幕的 1/4(见附件)。
代码:
struct MyCategoryRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 0) {
ForEach(0...2, id: \.self) { block in
ColoredBlock()
}.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)
}
}
}
所以上面的代码生成了一个 HStack,其中包含 3 个等宽的彩色块。我尝试使用 UIScreen.main.bounds.width 强制宽度,但该方法不适应方向的变化。我也试过像这样使用 GeometryReader:
GeometryReader { g in
ColoredBlock().frame(width: block == 0 ? g.size.width * 2 : g.size.width / 2)
}
但这也没有用,似乎每个ColoredBlock将占用HStack的1/3是事先决定的。
使用 layoutPriority 尝试更新:
struct MyCategoryRow: View {
var body: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 0) {
ForEach(0...2, id: \.self) { block in
ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2).layoutPriority(block == 0 ? 1.0 : 0.5)
}.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading)
}
}
}
struct ColoredBlock: View {
let background: Color
var body: some View {
GeometryReader { geometry in
VStack(spacing: 0){
HStack {
Text("Some text").padding(.horizontal, 15).padding(.top, 15)
}.frame(alignment: .leading)
VStack(alignment: .leading){
Text("Some more text").font(.subheadline).fontWeight(.light)
}.padding(.vertical, 10).padding(.horizontal, 15)
}.background(self.background)
.cornerRadius(15)
}
}
}
Result:
我想你需要的是.layoutPriority。将第一个块设置为 1.0,第二个和第三个块设置为 0.5。
我最后做的是在 MyCategoryRow 中使用 GeometryReader 而不是 ColoredBlock 并将宽度传递给 ColoredBlock
HStack {
ForEach(0...2, id: \.self) { block in
ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2, width: block == 0 ? geometry.size.width / 2 : geometry.size.width / 4, height: 150.0)
}
}
这可行,但现在我发现自己必须指定一个我不希望硬编码的高度。如果谁有更好的解决方案,请告诉我!