A flexible grid layout view for SwiftUI

Overview

๐Ÿ“ฑ GridStack

A flexible grid layout view for SwiftUI.

WWDC20 Update

Apple ๏ฃฟ released LazyVGrid and LazyHGrid at WWDC20.

If you are fine to only support i(Pad)OS 14, macOS 11, tvOS 14, watchOS 7 respectively those ^-- are definitely the way to go.

If you want to support i(Pad)OS 13, macOS 10.15, tvOS 13, watchOS 6 keep on reading.


Release Build & Test

๐Ÿ“ฑ iOS 13+, ๐Ÿ’ป macOS 10.15+, ๐Ÿ“บ tvOS 13+, โŒš watchOS 6+

Simply pass the minimum width the grid cells should have and the spacing between them and it will adjust depending on the available width.

So writing this:

Code

will give you you this:

Screenshot 2019-07-14 at 14 07 02

It also adjusts correctly when the device is rotated:

rotation

๐Ÿ—บ Usage Overview

Think of the grid in the way of what is the minimum width you want your cells to be. That way it is easy to adjust to any available space. The only other size you need to provide is the spacing between the cells.

To actually create the grid we need to know the numbers of items. Then the content view builder will be called with each index and the cellWidth that you can then pass to the frame of whatever you want to display inside.

๐Ÿ‘• Sizing your views inside the cells

The grid will wrap each item you provide with in a view that gets the cellWidth set as width. No height constraint is put on the cell. That is so that you can size your content as flexible as possible. Here are just a couple of examples what you can do.

Height defined by content

GridStack(...) { index, cellWidth in
    Text("\(index)")
        // Don't pass any height to the frame to let it be defined by it's content
        .frame(width: cellWidth)
}

Square items

GridStack(...) { index, cellWidth in
    Text("\(index)")
        // Pass the cellWidth as width and height to the frame to make a square
        .frame(width: cellWidth, height: cellWidth)
}

Aspect Ratio items

GridStack(...) { index, cellWidth in
    Text("\(index)")
        // Pass the cellWidth as width and a portion of it as height to get a certain aspect ratio
        .frame(width: cellWidth, height: cellWidth * 0.75)
}

โœ๏ธ Signature

GridStack(
    minCellWidth: Length,
    spacing: Length,
    numItems: Int,
    alignment: HorizontalAlignment = .leading,
    content: (index: Int, cellWidth: CGFloat) -> Void
)

๐Ÿ“ Mentions

I created GridStack by taking ideas from FlowStack by John Susek.

Comments
  • Not all shapes are showing

    Not all shapes are showing

    When i try to put a Circle() or Rectangle() inside the gridview these items do not show. When I add a button or text, they do show. Any idea what can be wrong?

    Btw .. When pairing the circle with text or button in a stack, both items show.

    opened by Bmorrhaye 5
  • Fix issue that the grid doesn't take the whole width

    Fix issue that the grid doesn't take the whole width

    Firstly thanks for sharing this!

    Say I have a grid of 15 items with minWidth 100, and they layout nicely in 3 columns. Now if I filter them into 1 item, then only the center column is shown with that item (which is correct). Upon tapping on the item I push a view, then when the view pops and I clear the filter so items are back to 15, the resulting grid would still retain the 1 column width and won't expand back into the full view.

    A google search yields many SO posts about the issue e.g. https://stackoverflow.com/questions/56534772/foreach-inside-scrollview-doesnt-take-whole-width

    Setting GeometryReader's width into the VStack solves the problem.

    This PR also adds edgeInsets so can specify spacing on each side.

    opened by hyouuu 4
  • Card Design

    Card Design

    Great Framework, For my App, I'm trying to recreate a similar Card design you used in the Preview Pictures for this library. Could you share the code you used to create the Card Views? Would be really Awesome

    Thanks Alot!

    opened by julianfbeck 2
  • Prevent stride being called with non-positive Int

    Prevent stride being called with non-positive Int

    Hi @pietropizzi, it's me again. Thanks for your quick reaction this morning!

    We might need another release as stride doesn't work that well when the requested size is zero.

    I tested this now against my use case and there are no errors/crashes anymore. ๐Ÿคž

    opened by danurna 1
  • Prevent negative layout results in case the available width is zero

    Prevent negative layout results in case the available width is zero

    Hello there and thanks for this great library. Still got to support iOS 13 so I am glad it exists.

    I've stumbled upon the issue of negative frame sizes being requested myself when using the GridStack inside a NavigationView (see related Apple Forum Thread). This is in line with the issue that has already been reported here: https://github.com/pietropizzi/GridStack/issues/16.

    The provided fix is quite simple. Please let me know what you think. Cheers!

    opened by danurna 1
  • Height is not compact but full

    Height is not compact but full

    The library is based on ScrollView, which by default is full-screen height. Is there a better way to make its height as compact as possible without manually assigning frame height?

    image

    opened by ghost 1
  • The Animation when the device rotated

    The Animation when the device rotated

    Why not create a smooth animation for this framework. My Requirement: When the device rotated, all of the grid will move smoothly to its new position.

    Thanks.

    opened by LiYanan2004 1
  • HELP WANTED. How to use your GridStack with Dictionary

    HELP WANTED. How to use your GridStack with Dictionary

    I have this simple code to test your GridStack, but it doesn't work as I wish.

    import GridStack
    import SwiftUI
    
    struct ContentView: View {
        
        let singers = ["Andrea","Alessia","Kofi", "Abena", "Efua", "Kweku", "Akosua", "Alberto", "Erika", "Antonio", "Anastasia","Annarita","Anna"]
        
        @State var groupedByFirst: [Character : [String]] = [" " : [""]]
        
        var body: some View {
            ForEach(self.groupedByFirst.keys.sorted{$0<=$1}, id: \.self) { char in
                Section(header: Text("Section: \(String(char))")) {
                    NavigationView{
                        GridStack(minCellWidth: 100, spacing: 5, numItems: self.groupedByFirst[char]!.count, alignment: .leading) { index, width in
                            NavigationLink(destination: Text(self.returnArrayOfString(char: char)[index])) {
                                CellView(string: self.returnArrayOfString(char: char)[index])
                            }
                        }
                }
                .navigationViewStyle(StackNavigationViewStyle())
            }
            .onAppear {
                self.groupedByFirst = Dictionary(grouping: self.singers, by: { $0.first! })
            }
        }
       
        func returnArrayOfString(char:Character) -> [String] {
            return self.groupedByFirst[char]!
        }
    }
    

    I wish the items (for example the images) were presented as in Photos (for example for the dates) and by clicking on it you can switch to another view, but I cannot make it work. Can You help me?

    opened by CPiersigilli 1
  • Add macOS and tvOS platforms

    Add macOS and tvOS platforms

    It looks like this project works just fine on macOS and tvOS SwiftUI, it just needs to have support added for it in the Package.swift file.

    image

    (watchOS has issues running the tests on my machine so I'm not enabling it here, but feel free to add it if it's running for you and it works)

    opened by stevestreza 1
  • Fix stride error

    Fix stride error

    Hi @pietropizzi, it's me again. Thanks for your quick reaction this morning!

    We might need another release as stride doesn't work that well when the requested size is zero and, in addition to that, using zero as the columnWidth is a problem as well.

    I tested this now against my use case and there are no errors/crashes anymore. ๐Ÿคž

    opened by danurna 0
  • cellWidth is negative

    cellWidth is negative

    Screen Shot 2564-03-12 at 17 58 13
    struct ContentView: View {
        
        // Setup
        init() {
            UITableView.appearance().backgroundColor = .clear
            // UITableViewCell.appearance().backgroundColor = .clear
        }
        
        var body: some View {
            NavigationView{
                Sidebar()
                    .navigationTitle("Recon")
                GridStack(minCellWidth: 300, spacing: 2, numItems: 15) { (index, cellWidth) in
                    Text("\(index)")
                        .frame(width: cellWidth, height: 100)
                        .background(Color.blue)
                } 
            }
        }
    }
    
    opened by chatsopond 1
  • GridStack used inside a VStack

    GridStack used inside a VStack

    Hi!

    So I'm in a situation where I want a horizontal list of items that also stack verticaly when too much items are sent to it, and your tool is perfect for that job <3

    ...but! I also want it to be on top of a multiline text view, so I put both in a VStack.

    The thing is that by doing that, the GridStack and the text view take each half the VStack's height. I looked into the GridStack's code because I expected it to take as small space as possible but I came accros a GeometryReader surrounding the elements, and this is understandable because you need to know the available width to work. But I know the GeometryReader doesn't shrink to it compact size but rather always take all the space it can, wether its content takes less or not. And it all made sense then!

    I've copied your GridStack locally in my project to work on it, and by removing the GeometryReader and sending the width to the GridStack (and removing the ScrollView too because of the same behavior), it all worked perfectly for my intention!

    So here is (finaly) my proposal:

    • making the scroll feature optional
    • removing the GeometryReader and let the "upper" view sending the desired width to the GridStack
    • (optionnaly, for the sake of easing the use of most cases) using an enum as the width with a case like "auto" that will add your current GeometryReader so that the "upper" view won't have to use a GeometryReady if it deosn't need to

    Here is the result I targeted, the GridStack is (obviously) the row of circles Capture dโ€™eฬcran 2021-02-19 aฬ€ 18 25 01

    opened by Khronoss 0
  • Drag and move to reorder support please

    Drag and move to reorder support please

    I am looking for a SwiftUI component like LazyGrid (https://stackoverflow.com/questions/62606907/swiftui-using-ondrag-and-ondrop-to-reorder-items-within-one-single-lazygrid), but needs to be forward compatible with iOS 13.x or macOS 10.15.x.

    Does GridStack have this feature please?

    opened by donly 0
  • How to expand GridStack to its full intrinsic height?

    How to expand GridStack to its full intrinsic height?

    My cell looks like this:

    struct CollectionCell: View {
        var type: PokemonTypes
        
        var body: some View {
    
            HStack {
                Image(type.imageName)
                
                Divider()
    
                GeometryReader { geometry in
    
                    GridStack(minCellWidth: geometry.size.width / 2,
                              spacing: 0,
                              numItems: self.type.superEffectiveAgainst.count) { index, cellWidth in
                        
                                Image(self.type.superEffectiveAgainst[index].imageName)
                                .frame(width: cellWidth)
                    }
                }
            }
        }
    }
    

    And it looks like that in the preview: Bildschirmfoto 2020-07-24 um 12 50 15

    The problem is that it shows only one row and I can scroll inside the table row when there are more than 2 items. How can I expand the GridStack to its full height?

    Thanks!

    opened by NickAtGit 0
Releases(0.4.3)
Owner
Peter Minarik
Web ๐Ÿ‘จโ€๐Ÿ’ป turned iOS ๐Ÿ‘จโ€๐Ÿ’ป
Peter Minarik
Building An Interactive Grid View

Building An Interactive Grid View This demo shows a few techniques on how to build a re-ordable grid view based on stock UICollectionView API. Here ar

Brian Coyner 8 Nov 14, 2022
Typed, yet Flexible Table View Controller

ConfigurableTableViewController Simple view controller that provides a way to configure a table view with multiple types of cells while keeping type s

Arek Holko 270 Oct 15, 2022
๐ŸŽ› QGrid: The missing SwiftUI collection view.

[NOTE] If you'd like to see QGrid in action, check out this demo of QDesigner (see video below). Install QDesigner: https://apps.apple.com/us/app/qdes

Q Mobile 1.5k Dec 23, 2022
Display list of Marvel comic Characters and its detail view

Marvel Universe Display list of Marvel comic Characters and its detail view Installation Dependencies in this project are provided via Xcodegen (proje

null 1 Oct 19, 2021
Use Yelp API to fetch restuarants around a location and show them in a table view

Yelp Use Yelp API to fetch restuarants around a location and show them in a table view - Infinite scrolling, Prefetching, Image Caching. Design Patter

null 0 Nov 1, 2021
Using UI Table View

News-App Table View์™€ Table view controller Table View : Table์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. Table View Controller: ์ „์ฒด์˜ ๋ทฐ๊ฐ€ ํ•˜๋‚˜์˜ ํ…Œ์ด๋ธ” Table View Table view ๊ตฌ์„ฑ์š”์†Œ ๊ฒฐ์ •ํ•˜๊ธฐ ์–ด๋–ค

Jiwon 0 Dec 9, 2021
An easy-to-use UITableViewCell subclass that implements a swippable content view which exposes utility buttons (similar to iOS 7 Mail Application)

SWTableViewCell An easy-to-use UITableViewCell subclass that implements a swipeable content view which exposes utility buttons (similar to iOS 7 Mail

Christopher Wendel 7.2k Dec 31, 2022
Objective-C library for drag-n-drop of UITableViewCells in a navigation hierarchy of view controllers.

ios-dragable-table-cells Support for drag-n-drop of UITableViewCells in a navigation hierarchy of view controllers. You drag cells by tapping and hold

Anders Borum 49 Aug 23, 2022
Generic table view controller with external data processing

FlexibleTableViewController Swift library of generic table view controller with external data processing of functionality, like determine cell's reuse

Dmytro Pylypenko 9 May 20, 2018
Simple timeline view implemented by UITableViewCell

TimelineTableViewCell TimelineTableViewCell is a simple timeline view implemented by UITableViewCell. The UI design of TimelineTableViewCell is inspir

Zheng-Xiang Ke 1.3k Dec 25, 2022
A UITableView extension that enables cell insertion from the bottom of a table view.

ReverseExtension UITableView extension that enabled to insert cell from bottom of tableView. Concept It is difficult to fill a tableview content from

Taiki Suzuki 1.7k Dec 15, 2022
TableViews - Emoji Table View For iOS With Swift

TableViews Hello! This is EmojiTableView. Let me introduce you my first app when

null 0 Jan 2, 2022
SpanGrid is an enriched SwiftUI LazyVGrid that supports a number of extra features.

SpanGrid is an enriched SwiftUI LazyVGrid that supports a number of extra features.

James Sherlock 6 Dec 17, 2022
APDynamicGrid is a SwiftUI package that helps you create consistent and animatable grids.

APDynamicGrid Overview APDynamicGrid is a SwiftUI package that helps you create consistent and animatable grids. The DynamicGrid View preserves the sa

Antonio Pantaleo 29 Jul 4, 2022
This framework allows you to build Table views using UIKit with syntax similar to SwiftUI

This framework allows you to build Table views using UIKit with syntax similar to SwiftUI

Fun 60 Dec 17, 2022
A waterfall grid layout view for SwiftUI.

WaterfallGrid A waterfall grid layout view for SwiftUI. Features Irregular grid of content. Columns number different per device orientation. Spacing a

Paolo Leonardi 1.9k Jan 7, 2023
A grid layout view for SwiftUI

Update July 2020 - latest SwiftUI now has built-in components to do this, which should be used instead. FlowStack FlowStack is a SwiftUI component for

John Susek 147 Nov 10, 2022
SwiftUI Grid layout with custom styles

SwiftUI Grid SwiftUI Grid view layout with custom styles. Features ZStack based layout Vertical and horizontal scrolling Supports all apple platforms

SpaceNation 928 Dec 15, 2022
Full aspect ratio grid layout for iOS

Greedo Layout for iOS A library that computes what size the UICollectionView cells should be to display images in a variable height fixed aspect ratio

500px 831 Dec 17, 2022