我对 swift 有点陌生,正在努力解决这个看似简单的问题。我希望网格中包含三列,除非网格项的内容不适合列的设置宽度。具体来说,我有过滤器按钮,其中一些按钮的名称很长。我想将“早餐”的 TagView 发送到下一行并移动每个标签视图,以便它们全部适合并且文本不必换行。但不知道如何做到这一点。
我尝试调整网格项中的最小值和最大值,并调整列中的 GridItem 数量。然而,不幸的是,这并没有奏效。任何建议将不胜感激。
这是我的代码:
var filterBar: some View {
VStack {
filterBarTitle
if filtersOpened {
let columns = [GridItem(.adaptive(minimum: 85), spacing:0)]
LazyVGrid(columns: columns) {
ForEach(allRecipeTags) { recipeTag in
TagView(tag: recipeTag, selected: selectedTags.contains(recipeTag), canToggle: true, onTap: {
if selectedTags.contains(recipeTag) {
print("removing \(recipeTag)")
selectedTags.removeAll(where: { $0 == recipeTag })
} else {
print("adding \(recipeTag)")
selectedTags.append(recipeTag)
}
})
.border(.red)
}
}
.border(.blue)
}
}
.padding([.top, .bottom])
.border(width: 1, edges: [.bottom], color: Color("24292F").opacity(0.3))
.padding(.horizontal)
.padding([.bottom], filtersOpened ? 8 : 0)
}
Run Code Online (Sandbox Code Playgroud)
这是一个自定义的简单实现Layout,希望适合您的目的:
struct ContentView: View {
let tags = ["Appetizers","Baking","Breakfast","Dessert","Dinner","Fish","Lunch","Main","Quick","Side","Snack","Spicy","Vegan","Vegetarian"]
var body: some View {
FlowLayout {
ForEach(tags, id: \.self) { tag in
HStack {
Text(tag)
.fixedSize()
.font(.headline)
Circle()
}
.padding(10)
.background(
Capsule().stroke(.red)
)
.padding(5)
}
}
}
}
struct FlowLayout: Layout {
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
var totalHeight: CGFloat = 0
var totalWidth: CGFloat = 0
var lineWidth: CGFloat = 0
var lineHeight: CGFloat = 0
for size in sizes {
if lineWidth + size.width > proposal.width ?? 0 {
totalHeight += lineHeight
lineWidth = size.width
lineHeight = size.height
} else {
lineWidth += size.width
lineHeight = max(lineHeight, size.height)
}
totalWidth = max(totalWidth, lineWidth)
}
totalHeight += lineHeight
return .init(width: totalWidth, height: totalHeight)
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
let sizes = subviews.map { $0.sizeThatFits(.unspecified) }
var lineX = bounds.minX
var lineY = bounds.minY
var lineHeight: CGFloat = 0
for index in subviews.indices {
if lineX + sizes[index].width > (proposal.width ?? 0) {
lineY += lineHeight
lineHeight = 0
lineX = bounds.minX
}
subviews[index].place(
at: .init(
x: lineX + sizes[index].width / 2,
y: lineY + sizes[index].height / 2
),
anchor: .center,
proposal: ProposedViewSize(sizes[index])
)
lineHeight = max(lineHeight, sizes[index].height)
lineX += sizes[index].width
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
678 次 |
| 最近记录: |