ios - SwiftUI LazyVGrid 动态行高
问题描述
我想要一个具有相同高度的 LazyVGrid 行扩展/收缩以填充可用的父高度
可能吗?
let columns = Array(repeating: GridItem(.flexible(minimum: 50, maximum: 100)), count: 3)
LazyVGrid(columns: columns, alignment: .leading, spacing: 10) {
ForEach(objects, id: \.self.id) { object in
MyView().frame(minHeight: 0, maxHeight: .infinity)
}
}
上面的代码确实在宽度上完美地分隔了框架,但行不会扩大和缩小,它们只会紧贴内容的高度。
解决方案
这是一个采用所有可用高度的网格示例。可以用更通用的方式来做,但我希望如何做的想法很清楚。
struct ContentView: View {
let numOfItems = 10
let numOfColumns = 3
let spacing: CGFloat = 10
var body: some View {
GeometryReader { g in
let columns = Array(repeating: GridItem(.flexible(minimum: 50, maximum: 100)), count: numOfColumns)
let numOfRows: Int = Int(ceil(Double(numOfItems) / Double(numOfColumns)))
let height: CGFloat = (g.size.height - (spacing * CGFloat(numOfRows - 1))) / CGFloat(numOfRows)
LazyVGrid(columns: columns, alignment: .leading, spacing: spacing) {
ForEach(0..<numOfItems, id: \.self) { object in
MyView().frame(minHeight: height, maxHeight: .infinity)
}
}
}
}}
struct MyView: View {
var body: some View {
Color(red: Double.random(in: 0...1), green: Double.random(in: 0...1), blue: Double.random(in: 0...1))
}
}
这是这样一个网格的可重用版本:
struct ContentView: View {
let colors = [UIColor.red, .black, .blue, .brown, .gray, .green, .cyan, .magenta, .orange, .purple]
var body: some View {
TallVGrid(items: colors, idKeyPath: \.self, numOfColumns: 4, vSpacing: 20, content: { color in
ColorView(uiColor: color)
Text("Some \(Int.random(in: 0...10))")
})
}
}
struct TallVGrid<Item, ItemView, I>: View where ItemView: View, I: Hashable {
var items: [Item]
var idKeyPath: KeyPath<Item, I>
var numOfItems : Int {
items.count
}
var numOfColumns : Int = 3
var vSpacing: CGFloat = 10
@ViewBuilder var content: (Item) -> ItemView
var body: some View {
GeometryReader { g in
let columns = Array(repeating: GridItem(.flexible(minimum: 50, maximum: 100)), count: numOfColumns)
let numOfRows: Int = Int(ceil(Double(numOfItems) / Double(numOfColumns)))
let height: CGFloat = (g.size.height - (vSpacing * CGFloat(numOfRows - 1))) / CGFloat(numOfRows)
LazyVGrid(columns: columns, alignment: .leading, spacing: vSpacing) {
ForEach(items, id: idKeyPath) { item in
VStack {
content(item)
}
.frame(minHeight: height, maxHeight: .infinity)
}
}
}
}
}
struct ColorView: View {
let uiColor: UIColor
var body: some View {
Color(uiColor)
}
}
推荐阅读
- reactjs - 针对特定组件的 React Router Links
- c - 为什么这个 C 程序的输出是 64 而不是 320?
- laravel - 如何检查插入是否执行?
- node.js - node.js for 循环不使用 continue 命令循环
- python - 保护 psycopg2 连接的明文密码字符串?
- highcharts - Highchart Pie 聊天不显示 Codeigniter
- sql - SQL Server:如何显示 case 语句中的占位符行?
- ruby - 由于旧的 libxml2,厨师命令失败
- amazon-web-services - AWS CloudFormation 转换 - 如何正确返回错误消息?
- ace-editor - 更改在 ace-editor 中为令牌显示的文本