SwiftUI LazyVGrid not showing two columns

Viewed 1039

I am playing with LazyVGrid in my beta version of Xcode, and I'm trying to make a vertical ScrollView show up with two columns instead of one. I have this view set up to include a ScrollView that checks if iOS 14 is available, and if so, renders the view as a two column grid (I put the columns inside this instance of LazyVGrid rather than as an external property because I didn't want to have to mark the whole View with the #available property - although maybe I should).

However, when I preview the view, it shows up with only one column. Is there anything in my setup that might be causing my view to only show up with one column instead of two?

Related - is there an easy way to preview in Xcode with different builds that do/don't include iOS 14? (In case my issue is that my preview version doesn't have iOS 14).

Here is my view for reference:

struct PackPage: View {
    @Binding var isPresented: Bool
    var allPacks: [Pack] = [samplePack, couplesPack, roadTripPack, familyPack]
    var purchasedPacks: [Pack] = [samplePack]
    var unpurchasedPacks: [Pack] = [couplesPack, roadTripPack, familyPack]

    let userDefaults = UserDefaults.standard
    @State private var action: Int? = 0
    @State private var linkLock: Pack? = samplePack
    
    private func isPurchased(pack: Pack, allPacks: [Pack]) -> Bool {
        if allPacks.contains(pack) {
            return true
        } else {
            return false
        }
    }

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: PurchasePage(pack: linkLock!), tag: 1, selection: $action) {
                    EmptyView()
                }
                ScrollView(.vertical, showsIndicators: false) {
                    ForEach((allPacks), id: \.self) { pack in
                        
                        //Checks if iOS version 14.0 is available to render the lazy grid view
                        if #available(iOS 14.0, *) {
                            LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 20) {
                                if
                                    //checks if the pack is in the purchased list - if so, renders it as an unlocked tile.
                                    isPurchased(pack: pack, allPacks: purchasedPacks) {
                                    UnlockedPackTile(tilePack: pack)
                                        .onTapGesture {
                                            print("Originally tapped \(pack.name)")
                                            self.userInformation.defaultPack = pack
                                            self.isPresented.toggle()
                                        }
                                } else {
                                    // if pack is not purchased, renders it as a locked pack tile
                                    LockedPackTile(tilePackLocked: pack)
                                        .onTapGesture {
                                            self.linkLock = pack
                                            self.action = 1
                                        }
                                }
                            }
                        } else {
                            //does this as a simple VStack instead if iOS 14 is not available.
                            if isPurchased(pack: pack, allPacks: purchasedPacks) {
                                UnlockedPackTile(tilePack: pack)
                                    .onTapGesture {
                                        print("Originally tapped \(pack.name)")
                                        self.userInformation.defaultPack = pack
                                        self.isPresented.toggle()
                                    }
                            } else {
                                LockedPackTile(tilePackLocked: pack)
                                    .onTapGesture {
                                        self.linkLock = pack
                                        self.action = 1
                                    }
                            }
                        }
                            }
                        }
                Text("Button")
        .navigationBarTitle("Question Packs")
        }
    }
}
}
1 Answers

You have to put ForEach inside LazyVGrid, so latter arranges dynamic views:

ScrollView(.vertical, showsIndicators: false) {
    //Checks if iOS version 14.0 is available to render the lazy grid view
    if #available(iOS 14.0, *) {
        LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 20) {
           ForEach((allPacks), id: \.self) { pack in

Related