โจGrid
โฌ๏ธ ้่ฆ๏ผ GridLayout, arr.index(of:), .if(_:then:)
/*
* โญ๏ธ Required:
* - ๐View + if
* - ๐Array + index
* - ๐ฆ GridLayout
*/
import SwiftUI
// ๐
Grid
public struct Grid<Item: Identifiable, ItemView: View>: View {
let items : [Item] // items to arrange
let viewForItem : (Item) -> ItemView // turn item into some View
let cellAspectRatio: CGFloat // desired cell aspect ratio
let showCellBorder : Bool // show cell border or not
// Grid(items){ item in ... }
public init(
_ items: [Item],
cellAspectRatio: CGFloat = 1, // โญ๏ธ default: aspect ratio = 1
showCellBorder : Bool = false, // โญ๏ธ default: don't show cell border
viewForItem : @escaping (Item) -> ItemView
) {
self.items = items
self.viewForItem = viewForItem
self.cellAspectRatio = cellAspectRatio
self.showCellBorder = showCellBorder
}
public var body: some View {
// โญ๏ธ GeometryReader
GeometryReader { geo in self.itemViews(in: geo.size) }
}
// helper functions
func itemViews(in size: CGSize) -> some View {
let n = items.count
// โญ๏ธ prepare best layout for items (require: ๐ฆ GridLayout)
let layout = GridLayout(itemCount: n, in: size, nearAspectRatio: cellAspectRatio)
// โญ๏ธ ForEach
return ForEach(items) { item in self.view(for: item, in: layout) }
}
func view(for item: Item, in layout: GridLayout) -> some View {
let index = items.index(of: item)! // ๐Array + index
let center = layout.centerOfCell(at: index) // ๐ฆ GridLayout
return viewForItem(item)
// โญ๏ธ best layout cell size
.frame(layout.cellSize)
// show cell border or not
.if(showCellBorder) { $0.border(Color.black) } // ๐View + if
// โ ๏ธ ๆณจๆ๏ผ
// ไธๆฆๅ ไธ .position ไนๅพ๏ผ.frame ๆ่ฎๆๆดๅ
// GeometryReader ็ๅคงๅฐ๏ผไธๅๆฏๅฎไธๅก็็ๅคงๅฐใ
// โญ๏ธ put item view at the right position
.position(center)
}
}
GridLayout - help calculate best layout.
stack - SwiftUI views for 1D layout.
Grids - SwiftUI views for 2D layout.
used in Emoji Memory Game ๐
.grids() - draw grid lines in the background.
MyGrid ๆน็ทจ่ช้่ฃกใ
Last updated