### Swift Grid Flow Example (Rows vs. Columns) Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates how to switch the grid flow between .rows and .columns using a @State variable and a button. This example shows the basic setup for controlling grid direction. ```swift struct ContentView: View { @State var flow: GridFlow = .rows var body: some View { VStack { if self.flow == .rows { Button(action: { self.flow = .columns }) { Text("Flow: ROWS") } } else { Button(action: { self.flow = .rows }) { Text("Flow: COLUMNS") } } Grid(0..<15, tracks: 5, flow: self.flow, spacing: 5) { ColorView($0.isMultiple(of: 2) ? .black : .orange) .overlay( Text(String($0)) .font(.system(size: 35)) .foregroundColor(.white) ) } .animation(.default) } } } ``` -------------------------------- ### Build Grid from Sources Source: https://github.com/exyte/grid/blob/master/README.md Instructions for cloning the Grid repository, installing dependencies using CocoaPods, and opening the example project in Xcode. ```shell git clone git@github.com:exyte/Grid.git cd Grid/Example/ pod install open Example.xcworkspace/ ``` -------------------------------- ### Install Grid with CocoaPods Source: https://github.com/exyte/grid/blob/master/README.md This snippet shows how to add the Grid library to your project using CocoaPods by adding 'ExyteGrid' to your Podfile. ```ruby pod 'ExyteGrid' ``` -------------------------------- ### Setting Explicit Start Positions for Grid Items Source: https://github.com/exyte/grid/blob/master/README.md Shows how to precisely position grid items using the .gridStart modifier, specifying both column and row. Views are auto-placed if no start position is defined. The library prioritizes placement for views with both row and column starts, then for views with one specified, and finally for auto-placed views. ```swift Grid(tracks: [.pt(50), .fr(1), .fr(1.5), .fit]) { ForEach(0..<6) { _ in ColorView(.black) } ColorView(.brown) .gridSpan(column: 3) ColorView(.blue) .gridSpan(column: 2) ColorView(.orange) .gridSpan(row: 3) ColorView(.red) .gridStart(row: 1) .gridSpan(column: 2, row: 2) ColorView(.yellow) .gridStart(row: 2) ColorView(.purple) .frame(maxWidth: 50) .gridStart(column: 3, row: 0) .gridSpan(row: 9) ColorView(.green) .gridSpan(column: 2, row: 3) ColorView(.cyan) ColorView(.gray) .gridStart(column: 2) } ``` -------------------------------- ### Swift Grid Content Mode: Scroll (Columns Flow) Source: https://github.com/exyte/grid/blob/master/README.md Illustrates setting the grid content mode to .scroll for a grid with columns flow. This example uses a custom `HCardView` and applies `.gridContentMode`, `.gridFlow`, and `.gridPacking` modifiers. ```swift struct HCardView: View { let text: String let color: UIColor var body: some View { HStack { Image("dog") .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(5) Text(self.text) .frame(maxWidth: 200) } .padding(5) .gridCellBackground { _ in ColorView(self.color) } .gridCellOverlay { _ in RoundedRectangle(cornerRadius: 5) .strokeBorder(Color(self.color.darker()), lineWidth: 3) } } } struct ContentView: View { var body: some View { Grid(tracks: 3) { ForEach(0..<8) { HCardView(text: randomText(), color: .random) .gridSpan(row: self.randomSpan) } } .gridContentMode(.scroll) .gridFlow(.columns) .gridPacking(.dense) } var randomSpan: Int { Int(arc4random_uniform(3)) + 1 } } ``` -------------------------------- ### SwiftUI Grid Handling Outer Data Changes in @GridBuilder Source: https://github.com/exyte/grid/blob/master/README.md Addresses an issue where Grid content using outer data (like @State variables) might not update. This example demonstrates the problem and the expected behavior with state changes. ```swift import SwiftUI struct ContentView: View { @State var titleText: String = "Initial Title" var body: some View { Grid(tracks: 2) { Text(titleText) Text("Static Text") } .onAppear { // Simulate a data change DispatchQueue.main.asyncAfter(deadline: .now() + 2) { titleText = "Updated Title" } } } } ``` -------------------------------- ### Initialize Grid with Content-Based Fit Tracks Source: https://github.com/exyte/grid/blob/master/README.md Initializes a Grid using a range of integers and track sizes set to '.fit'. Each track will automatically adjust its size to accommodate the maximum content size within that track. ```swift Grid(0..<6, tracks: [.fit, .fit, .fit]) { ColorView(.random) .frame(maxWidth: 50 + 15 * CGFloat($0)) } ``` -------------------------------- ### Initialize Grid using Range Source: https://github.com/exyte/grid/blob/master/README.md Initializes a Grid by specifying a range of integers for content generation and the number of tracks. A closure is used to create views for each element in the range. ```swift Grid(0..<6, tracks: 3) { ColorView(.random) } ``` -------------------------------- ### Initialize Grid with Tracks and Views Source: https://github.com/exyte/grid/blob/master/README.md Initializes a Grid view by specifying the number of tracks and providing child views within a ViewBuilder closure. This is a straightforward way to create a grid layout. ```swift Grid(tracks: 3) { ColorView(.blue) ColorView(.purple) ColorView(.red) ColorView(.cyan) ColorView(.green) ColorView(.orange) } ``` -------------------------------- ### SwiftUI Grid Spacing: Int, Array, and Explicit Initializers Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates multiple ways to define spacing in SwiftUI Grids: using a single Int for uniform spacing, an array for distinct horizontal and vertical spacing, and an explicit GridSpacing initializer. ```swift import SwiftUI struct SpacingExample: View { @State var vSpacing: CGFloat = 0 @State var hSpacing: CGFloat = 0 var body: some View { VStack { // Assuming sliders are defined elsewhere // self.sliders Grid(tracks: 3, spacing: [hSpacing, vSpacing]) { ForEach(0..<21) { index in //Inner image used to measure size self.imagePlaceholder .aspectRatio(contentMode: .fit) .opacity(0) .gridSpan(column: max(1, index % 4)) .gridCellOverlay { //This one is to display self.imagePlaceholder .aspectRatio(contentMode: .fill) .frame(width: $0?.width, height: $0?.height) .cornerRadius(5) .clipped() .shadow(color: self.shadowColorPlaceholder, radius: 10, x: 0, y: 0) } } } .background(self.backgroundColorPlaceholder) .gridContentMode(.scroll) .gridPacking(.dense) } } // Placeholder for image view var imagePlaceholder: some View { Image(systemName: "photo") // Using a system image as a placeholder } // Placeholder for shadow color var shadowColorPlaceholder: Color { .gray } // Placeholder for background color var backgroundColorPlaceholder: Color { .white } } // Placeholder for Grid struct and modifiers struct Grid: View { let tracks: Int let spacing: GridSpacing let content: () -> Content init(tracks: Int, spacing: CGFloat = 0, @ViewBuilder content: @escaping () -> Content) { self.tracks = tracks self.spacing = GridSpacing(horizontal: spacing, vertical: spacing) self.content = content } init(tracks: Int, spacing: [CGFloat], @ViewBuilder content: @escaping () -> Content) { self.tracks = tracks self.spacing = GridSpacing(horizontal: spacing.first ?? 0, vertical: spacing.last ?? 0) self.content = content } init(tracks: Int, spacing: GridSpacing, @ViewBuilder content: @escaping () -> Content) { self.tracks = tracks self.spacing = spacing self.content = content } var body: some View { // Dummy implementation for compilation VStack { Text("Grid Placeholder") } } func gridContentMode(_ mode: GridContentMode) -> Self { return self } func gridPacking(_ packing: GridPacking) -> Self { return self } } // Placeholder for GridSpacing struct struct GridSpacing { var horizontal: CGFloat = 0 var vertical: CGFloat = 0 } // Placeholder for GridSpan modifier struct GridSpanModifier: ViewModifier { var column: Int = 1 func body(content: Content) -> some View { content } } struct GridSpan { var column: Int = 1 var row: Int = 1 } extension View { func gridSpan(column: Int = 1, row: Int = 1) -> some View { modifier(GridSpanModifier(column: column)) } func gridCellOverlay(@ViewBuilder _ overlayContent: @escaping (OverlayCoordinate?) -> OverlayContent) -> some View { self // Dummy implementation } func gridContentMode(_ mode: GridContentMode) -> Self { return self } func gridPacking(_ packing: GridPacking) -> Self { return self } func background(_ color: Color) -> some View { self // Dummy implementation } } // Placeholder for GridContentMode enum enum GridContentMode { case scroll } // Placeholder for GridPacking enum enum GridPacking { case dense } // Placeholder for OverlayCoordinate struct struct OverlayCoordinate { let width: CGFloat? let height: CGFloat? } ``` -------------------------------- ### Initialize Grid with Identifiable Entities Source: https://github.com/exyte/grid/blob/master/README.md Initializes a Grid using a collection of identifiable entities. The library iterates through these entities and creates a view for each one, using the entity's properties to define grid content. ```swift Grid(colorModels, tracks: 3) { ColorView($0) } ``` -------------------------------- ### SwiftUI Grid Packing: Sparse vs. Dense Source: https://github.com/exyte/grid/blob/master/README.md Illustrates the two grid packing strategies in SwiftUI: 'sparse' (default), which places items in order without filling holes, and 'dense', which attempts to fill holes with later, smaller items, potentially altering order. ```swift import SwiftUI struct PackingExample: View { @State var gridPacking = GridPacking.sparse var body: some View { VStack { // Assuming packingPicker is defined elsewhere // self.packingPicker Grid(tracks: 4) { ColorView(.red) ColorView(.black) .gridSpan(column: 4) ColorView(.purple) ColorView(.orange) ColorView(.green) } .gridPacking(self.gridPacking) .gridAnimation(.default) } } } // Placeholder for GridPacking enum enum GridPacking { case sparse, dense } // Placeholder for Grid struct and modifiers struct Grid: View { let tracks: Int let content: () -> Content init(tracks: Int, @ViewBuilder content: @escaping () -> Content) { self.tracks = tracks self.content = content } var body: some View { // Dummy implementation for compilation VStack { Text("Grid Placeholder") } } func gridPacking(_ packing: GridPacking) -> Self { return self } func gridAnimation(_ animation: GridAnimation) -> Self { return self } } // Placeholder for GridSpan modifier struct GridSpanModifier: ViewModifier { var column: Int = 1 func body(content: Content) -> some View { content } } struct GridSpan { var column: Int = 1 var row: Int = 1 } extension View { func gridSpan(column: Int = 1, row: Int = 1) -> some View { modifier(GridSpanModifier(column: column)) } } // Placeholder for ColorView struct ColorView: View { let color: Color init(_ color: Color) { self.color = color } var body: some View { Rectangle().fill(color) } } // Placeholder for GridAnimation enum enum GridAnimation { case `default` } ``` -------------------------------- ### Initialize Grid with Fixed-Sized Tracks Source: https://github.com/exyte/grid/blob/master/README.md Creates a Grid where each track has a fixed size defined in points. This allows for precise control over the dimensions of columns or rows in the grid layout. ```swift Grid(tracks: [.pt(50), .pt(200), .pt(100)]) { ColorView(.blue) ColorView(.purple) ColorView(.red) ColorView(.cyan) ColorView(.green) ColorView(.orange) } ``` -------------------------------- ### Create GridGroup using ForEach Source: https://github.com/exyte/grid/blob/master/README.md Constructs a GridGroup by utilizing a ForEach loop over a collection of MathOperation items. This method is suitable for dynamically populating a GridGroup with views based on data. ```swift var arithmeticButtons: GridGroup { let operations: [MathOperation] = \ [.divide, .multiply, .substract, .add, .equal] return GridGroup { ForEach(operations, id: \.self) { CalcButton($0) } } } ``` -------------------------------- ### Create GridGroup from Collection with ID Source: https://github.com/exyte/grid/blob/master/README.md Initializes a GridGroup using a collection of MathOperation items, specifying \.self as the identifier key path. This ensures each button has a unique identity for potential animations. ```swift var arithmeticButtons: GridGroup { let operations: [MathOperation] = \ [.divide, .multiply, .substract, .add, .equal] return GridGroup(operations, id: \.self) { CalcButton($0) } } ``` -------------------------------- ### Flexible Sized Tracks with Fractional Units (.fr) Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates using fractional units (.fr) for flexible track sizing in SwiftUI Grid. Fractional units distribute available space after fixed tracks are laid out. You can use decimal values for finer control over space distribution. An integer literal is a shorthand for repeating .fr(1) tracks. ```swift Grid(tracks: [.pt(100), .fr(1), .fr(2.5)]) { ColorView(.blue) ColorView(.purple) ColorView(.red) ColorView(.cyan) ColorView(.green) ColorView(.orange) } ``` ```swift Grid(tracks: 3) { ... } ``` ```swift Grid(tracks: [.fr(1), .fr(1), .fr(1)]) { ... } ``` -------------------------------- ### Create GridGroup with Views Source: https://github.com/exyte/grid/blob/master/README.md Creates a GridGroup containing multiple CalcButton views. GridGroup is used to manage a collection of views within a grid, especially when exceeding the default limit or needing explicit identity. ```swift var arithmeticButtons: GridGroup { GridGroup { CalcButton(.divide) CalcButton(.multiply) CalcButton(.substract) CalcButton(.equal) } } ``` -------------------------------- ### SwiftUI Grid Content Mode: Fill Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates the '.fill' content mode for a SwiftUI Grid, where the grid attempts to occupy the entire parent view space. Growing tracks are implicitly given a flexible size. ```swift import SwiftUI struct ContentView: View { @State var contentMode: GridContentMode = .scroll var body: some View { VStack { // Assuming modesPicker is defined elsewhere // self.modesPicker Grid(models, id: \.self, tracks: 3) { model in VCardView(text: model.text, color: model.color) .gridSpan(model.span) } .gridContentMode(self.contentMode) .gridFlow(.rows) .gridAnimation(.default) } } } // Placeholder for GridContentMode enum if not imported enum GridContentMode { case scroll, fill } // Placeholder for Grid struct and modifiers struct Grid: View where Data: RandomAccessCollection, ID: Hashable, Content: View { let data: Data let id: KeyPath let tracks: Int let content: (Data.Element) -> Content init(_ data: Data, id: KeyPath, tracks: Int, @ViewBuilder content: @escaping (Data.Element) -> Content) { self.data = data self.id = id self.tracks = tracks self.content = content } var body: some View { // Dummy implementation for compilation VStack { Text("Grid Placeholder") } } func gridContentMode(_ mode: GridContentMode) -> Self { return self } func gridFlow(_ flow: GridFlow) -> Self { return self } func gridAnimation(_ animation: GridAnimation) -> Self { return self } } // Placeholder for GridSpan modifier struct GridSpanModifier: ViewModifier { let span: GridSpan func body(content: Content) -> some View { content } } // Placeholder for GridSpan struct GridSpan { var column: Int = 1 var row: Int = 1 } // Placeholder for GridFlow enum enum GridFlow { case rows, columns } // Placeholder for GridAnimation enum enum GridAnimation { case fast, `default` } // Placeholder for VCardView struct VCardView: View { let text: String let color: Color var body: some View { Text(text).background(color) } } // Placeholder for sample data struct ItemModel: Identifiable { let id = UUID() let text: String let color: Color var span = GridSpan() } let models = [ItemModel(text: "1", color: .red), ItemModel(text: "2", color: .blue), ItemModel(text: "3", color: .green)] ``` -------------------------------- ### Initialize Grid with Explicit ID Source: https://github.com/exyte/grid/blob/master/README.md Initializes a Grid by providing a collection of models, an explicit ID key path, and the number of tracks. This allows for precise control over view identity within the grid, useful for animations. ```swift Grid(colorModels, id: \.self, tracks: 3) { ColorView($0) } ``` -------------------------------- ### GridGroup with Specific Content Identifier Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates adding a GridGroup to a Grid, where the GridGroup is initialized with a specific content identifier (MathOperation.clear) and a closure to create CalcButton views. ```swift Grid { ... GridGroup(MathOperation.clear) { CalcButton($0) } } ``` -------------------------------- ### Using ForEach within Grid Source: https://github.com/exyte/grid/blob/master/README.md Demonstrates the use of SwiftUI's ForEach statement within a Grid's ViewBuilder closure to dynamically generate multiple grid items. Note that using ForEach without identifiable data may affect animation tracking. ```swift Grid(tracks: 4) { ColorView(.red) ColorView(.purple) ForEach(0..<4) { ColorView(.black) } ColorView(.orange) ColorView(.green) } ``` -------------------------------- ### GridGroup with Collection and Explicit ID Source: https://github.com/exyte/grid/blob/master/README.md Initializes a GridGroup using a collection of MathOperation items and explicitly defining the identifier using a key path. This provides stable identifiers for views within the group. ```swift var arithmeticButtons: GridGroup { let operations: [MathOperation] = \ [.divide, .multiply, .substract, .add, .equal] return GridGroup(operations, id: \.self) { CalcButton($0) } } ``` -------------------------------- ### SwiftUI Grid Caching with .gridCaching() Source: https://github.com/exyte/grid/blob/master/README.md Enables caching of grid layouts throughout the Grid's lifecycle. Supported on iOS only. Caching can be set in the constructor or via the .gridCaching() modifier, with the constructor taking precedence. ```swift import SwiftUI struct ContentView: View { var body: some View { Grid { // ... content } .gridCaching(true) // Enable caching } } ``` -------------------------------- ### SwiftUI Grid Item and Content Alignment Source: https://github.com/exyte/grid/blob/master/README.md Configures alignment for grid items and the overall grid content in SwiftUI. '.gridItemAlignment' sets alignment for individual items, '.gridCommonItemsAlignment' applies to all items unless overridden, and '.gridContentAlignment' aligns the grid within its available space. ```swift import SwiftUI struct SingleAlignmentExample: View { var body: some View { Grid(tracks: 3) { TextCardView(text: "Hello", color: .red) .gridItemAlignment(.leading) TextCardView(text: "world", color: .blue) } .gridCommonItemsAlignment(.center) .gridContentAlignment(.trailing) } } struct TextCardView: View { let text: String let color: Color var textColor: Color = .white var body: some View { Text(self.text) .foregroundColor(self.textColor) .padding(5) .gridCellBackground { _ in ColorView(self.color) } .gridCellOverlay { _ in RoundedRectangle(cornerRadius: 5) .strokeBorder(self.color.darker(), lineWidth: 3) } } } // Placeholder for Grid struct and modifiers struct Grid: View { let tracks: Int let content: () -> Content init(tracks: Int, @ViewBuilder content: @escaping () -> Content) { self.tracks = tracks self.content = content } var body: some View { // Dummy implementation for compilation VStack { Text("Grid Placeholder") } } func gridItemAlignment(_ alignment: GridItemAlignment) -> Self { return self } func gridCommonItemsAlignment(_ alignment: GridItemAlignment) -> Self { return self } func gridContentAlignment(_ alignment: GridContentAlignment) -> Self { return self } } // Placeholder for GridItemAlignment enum enum GridItemAlignment { case leading, center, trailing } // Placeholder for GridContentAlignment enum enum GridContentAlignment { case leading, center, trailing } // Placeholder for ColorView struct ColorView: View { let color: Color init(_ color: Color) { self.color = color } var body: some View { Rectangle().fill(color) } } // Extension to provide a darker color for stroke extension Color { func darker(_ amount: CGFloat = 0.1) -> Color { // Dummy implementation for compilation return self } // Placeholder for gridCellBackground modifier func gridCellBackground(@ViewBuilder _ background: @escaping (OverlayCoordinate?) -> OverlayContent) -> some View { self // Dummy implementation } // Placeholder for gridCellOverlay modifier func gridCellOverlay(@ViewBuilder _ overlay: @escaping (OverlayCoordinate?) -> OverlayContent) -> some View { self // Dummy implementation } } // Placeholder for gridItemAlignment modifier struct GridItemAlignmentModifier: ViewModifier { let alignment: GridItemAlignment func body(content: Content) -> some View { content } } // Placeholder for gridCommonItemsAlignment modifier struct GridCommonItemsAlignmentModifier: ViewModifier { let alignment: GridItemAlignment func body(content: Content) -> some View { content } } // Placeholder for gridContentAlignment modifier struct GridContentAlignmentModifier: ViewModifier { let alignment: GridContentAlignment func body(content: Content) -> some View { content } } // Extending View to apply modifiers extension View { func gridItemAlignment(_ alignment: GridItemAlignment) -> some View { modifier(GridItemAlignmentModifier(alignment: alignment)) } func gridCommonItemsAlignment(_ alignment: GridItemAlignment) -> some View { modifier(GridCommonItemsAlignmentModifier(alignment: alignment)) } func gridContentAlignment(_ alignment: GridContentAlignment) -> some View { modifier(GridContentAlignmentModifier(alignment: alignment)) } } // Placeholder for OverlayCoordinate struct struct OverlayCoordinate { let width: CGFloat? let height: CGFloat? } ``` -------------------------------- ### SwiftUI @GridBuilder for Conditional Views Source: https://github.com/exyte/grid/blob/master/README.md Utilizes the @GridBuilder function builder to conditionally return different SwiftUI views within Grid or GridGroup bodies. This allows for dynamic view construction based on state or logic. ```swift import SwiftUI struct ContentView: View { var body: some View { Grid { headerSegment(flag: true) } } @GridBuilder func headerSegment(flag: Bool) -> some View { if flag { return GridGroup { Text("Conditional Content") } } else { return ColorView(.black) } } } struct ColorView: View { let color: Color var body: some View { color } } ``` -------------------------------- ### SwiftUI Grid Animation with .gridAnimation() Source: https://github.com/exyte/grid/blob/master/README.md Applies a specific animation to the inner ZStack of a Grid. Requires explicit IDs for views to ensure correct animation transitions, especially when using ForEach or GridGroup with Identifiable models. ```swift import SwiftUI struct ContentView: View { var body: some View { Grid { ForEach(0..<10) { Text("Item \($0)") .gridCell(id: $0) } } .gridAnimation(.default) } } ``` -------------------------------- ### Swift Grid Content Mode: Scroll (Rows Flow) Source: https://github.com/exyte/grid/blob/master/README.md Shows how to set the grid content mode to .scroll for a grid with rows flow. It includes a custom `VCardView` and demonstrates how to apply the modifier and other grid properties like `gridPacking` and `gridSpan`. ```swift struct VCardView: View { let text: String let color: UIColor var body: some View { VStack { Image("dog") .resizable() .aspectRatio(contentMode: .fit) .cornerRadius(5) .frame(minWidth: 100, minHeight: 50) Text(self.text) .layoutPriority(.greatestFiniteMagnitude) } .padding(5) .gridCellBackground { _ in ColorView(self.color) } .gridCellOverlay { _ in RoundedRectangle(cornerRadius: 5) .strokeBorder(Color(self.color.darker()), lineWidth: 3) } } } struct ContentView: View { var body: some View { Grid(tracks: 3) { ForEach(0..<40) { VCardView(text: randomText(), color: .random) .gridSpan(column: self.randomSpan) } } .gridContentMode(.scroll) .gridPacking(.dense) .gridFlow(.rows) } var randomSpan: Int { Int(arc4random_uniform(3)) + 1 } } ``` -------------------------------- ### Spanning Grid Cells Across Tracks Source: https://github.com/exyte/grid/blob/master/README.md Illustrates how to make grid items span across multiple columns or rows using the .gridSpan modifier. This is useful for creating more complex layouts where a single item occupies more than one cell. The span value defaults to 1 if not specified. ```swift Grid(tracks: [.fr(1), .pt(150), .fr(2)]) { ColorView(.blue) .gridSpan(column: 2) ColorView(.purple) .gridSpan(row: 2) ColorView(.red) ColorView(.cyan) ColorView(.green) .gridSpan(column: 2, row: 3) ColorView(.orange) ColorView(.magenta) .gridSpan(row: 2) } ``` ```swift var body: some View { Grid(tracks: [.fr(1), .fit, .fit], spacing: 10) { VCardView(text: placeholderText(), color: .red) VCardView(text: placeholderText(length: 30), color: .orange) .frame(maxWidth: 70) VCardView(text: placeholderText(length: 120), color: .green) .frame(maxWidth: 100) .gridSpan(column: 1, row: 2) VCardView(text: placeholderText(length: 160), color: .magenta) .gridSpan(column: 2, row: 1) VCardView(text: placeholderText(length: 190), color: .cyan) .gridSpan(column: 3, row: 1) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.