Skip to content
🚀 SwiftUI Grid with custom styles.
Branch: master
Clone or download
Latest commit 025fe64 Nov 24, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github Create FUNDING.yml Nov 7, 2019
Examples macos settings view (#37) Nov 24, 2019
Resources Modular and Staggered (#31) Nov 17, 2019
Sources/Grid settings (#33) Nov 18, 2019
.gitignore gitignore Jul 31, 2019
LICENSE bundle identifiers (#25) Oct 15, 2019
Package.swift tvOS (#17) Aug 25, 2019 settings (#33) Nov 18, 2019

SwiftUI Grid

SwiftUI Grid view layout with custom styles.


  • ZStack based layout
  • Vertical and horizontal scrolling
  • Supports all apple platforms
  • Custom styles (ModularGridStyle, StaggeredGridStyle)
  • SwiftUI code patterns (StyleStructs, EnvironmentValues, ViewBuilder)
  • Active development for production apps

Open /Examples/GridExamples.xcodeproj for more examples for iOS, macOS, watchOS and tvOS


ModularGridStyle (Default)

Grid(colors) {
    ModularGridStyle(columns: .min(100), rows: .min(100))


Grid(1...69, id: \.self) { index in
    StaggeredGridStyle(tracks: 8, axis: .horizontal, spacing: 4)


Tracks setting allows you to customize grid behaviour to your specific use-case. Both Modular and Staggered grid use tracks value to calculate layout. In Modular layout both columns and rows are tracks.

public enum Tracks: Hashable {
    case count(Int)
    case fixed(CGFloat)
    case min(CGFloat)


Grid is split into equal fractions of size provided by a parent view.

ModularGridStyle(columns: 3, rows: 3)
StaggeredGridStyle(tracks: 8)


Item size is fixed to a specific width or height.

ModularGridStyle(columns: .fixed(100), rows: .fixed(100))
StaggeredGridStyle(tracks: .fixed(100))


Autolayout respecting a min item width or height.

ModularGridStyle(columns: .min(100), rows: .min(100))
StaggeredGridStyle(tracks: .min(100))


Get item size and position with preferences

struct CardsView: View {
    @State var selection: Int = 0
    var body: some View {
        Grid(0..<100) { number in
            Card(title: "\(number)")
                .onTapGesture {
                    self.selection = number
        .overlayPreferenceValue(GridItemBoundsPreferencesKey.self) { preferences in
            RoundedRectangle(cornerRadius: 16)
                .strokeBorder(lineWidth: 4)
                    width: preferences[self.selection].width,
                    height: preferences[self.selection].height
                    x: preferences[self.selection].midX,
                    y: preferences[self.selection].midY


  • iOS 13+
  • Mac Catalyst 13.0+
  • macOS 10.15+
  • watchOS 6+
  • Xcode 11.0+


  • Animations
  • 'CSS Grid'-like features

Code Contibutions

Feel free to contribute via fork/pull request to master branch. If you want to request a feature or report a bug please start a new issue.

Coffee Contibutions

If you find this project useful please consider becoming a sponsor.

You can’t perform that action at this time.