繁体   English   中英

SwiftUI LazyVGrid 动态行高

[英]SwiftUI LazyVGrid dynamic row height

我想要一个具有相同高度的行的 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)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM