cs193p-memorize/Memorize/AspectVGrid.swift
Ching 990720f9d3 feat(view): 新增 pie 样式 view
新增 pie 样式 view

Signed-off-by: Ching <loooching@gmail.com>
2023-02-15 19:31:58 +08:00

67 lines
2.0 KiB
Swift

//
// AspectVGrid.swift
// Memorize
//
// Created by ching on 2023/2/13.
//
import SwiftUI
struct AspectVGrid<Item, ItemView>: View where ItemView: View, Item: Identifiable {
var items: [Item]
var aspectRatio: CGFloat
var content: (Item) -> ItemView
init(items: [Item], aspectRatio: CGFloat, @ViewBuilder content: @escaping (Item) -> ItemView) {
self.items = items
self.aspectRatio = aspectRatio
self.content = content
}
var body: some View {
GeometryReader { geometry in
VStack{
let width: CGFloat = widthThatFits(itemCount: items.count, in: geometry.size, itemAspectRatio: aspectRatio)
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
ForEach(items) {
item in content(item).aspectRatio(aspectRatio, contentMode: .fit)
}
}
Spacer(minLength: 0)
}
}
}
private func adaptiveGridItem(width: CGFloat) -> GridItem {
var gridItem = GridItem(.adaptive(minimum: width))
gridItem.spacing = 0
return gridItem
}
private func widthThatFits(itemCount: Int, in size: CGSize, itemAspectRatio: CGFloat) -> CGFloat {
var columCount = 1
var rowCount = itemCount
repeat {
let itemWidth = size.width / CGFloat(columCount)
let itemHeight = itemWidth / itemAspectRatio
if CGFloat(rowCount) * itemHeight < size.height {
break
}
columCount += 1
rowCount = (itemCount + columCount - 1) / columCount
} while columCount < itemCount
if columCount > itemCount {
columCount = itemCount
}
return floor(size.width / CGFloat(columCount))
}
}
// struct AspectVGrid_Previews: PreviewProvider {
// static var previews: some View {
// AspectVGrid()
// }
// }