๐Ÿ‘”VGridForEach

SwiftUI โŸฉ Layout โŸฉ Grids โŸฉ

// (*) v.1 (f) fix (r) refactor (+) new
// ---------------------------------------------------
// 2020.01.20 (*) : + VGridForEach, ScrollVGridForEach
// 2022.02.15 (f) : id: \.self
//            (r) : param order, rename `content` as `cellViewAtIndex`
//            (f) : @ViewBuilder cellViewAtIndex

import SwiftUI

// ------------------------
//     ๐Ÿ‘” VGridForEach
// ------------------------

/// ๐Ÿ‘” VGridForEach = LazyVGrid + ForEach
public struct VGridForEach<Content: View>: View  {
    
    // properties
    let data     : Range<Int>
    let columns  : [GridItem]               // fixed/adaptive/flexible
    let alignment: HorizontalAlignment      // alignment in cell
    let rowSpacing : CGFloat?               // row spacing
    let pinnedViews: PinnedScrollableViews  // ?
    // โญ ViewBuilder
    @ViewBuilder let cellViewAtIndex: (Int) -> Content   // cell view
    
    // body
    public var body: some View {
        LazyVGrid(                            // LazyVGrid
            columns  : columns, 
            alignment: alignment, 
            spacing  : rowSpacing, 
            pinnedViews: pinnedViews
        ) {
            ForEach(data, id: \.self) { i in  // ForEach
                self.cellViewAtIndex(i) 
            }
        }
    }
}

// convenience init
extension VGridForEach {
    public init(
        _ data   : Range<Int>,
        columns  : [GridItem],
        alignment  : HorizontalAlignment   = .center,
        rowSpacing : CGFloat?              = nil,
        pinnedViews: PinnedScrollableViews = .init(),
        // โญ ViewBuilder
        @ViewBuilder cellViewAtIndex: @escaping (Int) -> Content
    ) {
        // ForEach
        self.data = data
        // LazyVGrid
        self.columns     = columns
        self.alignment   = alignment
        self.rowSpacing  = rowSpacing
        self.pinnedViews = pinnedViews
        self.cellViewAtIndex = cellViewAtIndex
    }
}

History

  1. 2022.02.15

Last updated