spacenation / swiftui-grid

:rocket: SwiftUI Grid layout with custom styles

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

StaggeredGridStyle layout breaks when placed in a scrollview with other view

ethanyuwang opened this issue · comments

The grid with StaggeredGridStyle works fine when its the only view inside a ScrollView:

struct ProfileView: View {
    @Environment(\.imageCache) var cache: ImageCache
    @State var plants: [Plant] = [Plant]()
    
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                WaterfallGallery(urlPaths: plants.map() {$0.headerImage!.url}, cache: cache)
            }
            .navigationBarTitle("Overview", displayMode: .inline)
            .onAppear {
                self.plants = Plant.populateExampleData()
            }
        }
    }
}

Simulator Screen Shot - iPhone 11 Pro - 2020-08-08 at 22 04 52

However, if I add another view on top of it the layout breaks:

struct ProfileView: View {
    @Environment(\.imageCache) var cache: ImageCache
    @State var plants: [Plant] = [Plant]()
    
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                UserInfo()
                WaterfallGallery(urlPaths: plants.map() {$0.headerImage!.url}, cache: cache)
            }
            .navigationBarTitle("Overview", displayMode: .inline)
            .onAppear {
                self.plants = Plant.populateExampleData()
            }
        }
    }
}

Simulator Screen Shot - iPhone 11 Pro - 2020-08-08 at 22 05 03

Here is my WaterfallGallery:

struct WaterfallGallery: View {
    @ObservedObject var loader: ImagesLoader
    
    @State var urlPaths: [String]
    
    init(urlPaths: [String], cache: ImageCache? = nil) {
        var URLs = [URL]()
        for urlPath in urlPaths {
            //TODO: Provide defualt error image
            URLs.append(URL(string: urlPath)!)
        }
        self._urlPaths = State(initialValue: urlPaths)
        //TODO: provide cache
        self.loader = ImagesLoader(urls: URLs)
        self.loader.load()
    }
    
    var body: some View {
        Group {
            if self.loader.isLoading {
                placeHolder
            } else {
                gallery.onDisappear(perform: loader.cancel)
            }
        }
    }
    
    private var gallery: some View {
   
        Grid(0..<self.loader.images.count, id: \.self) { index in
            //TODO: Provide defualt failed to load image
            Image(uiImage: self.loader.images[index] ?? UIImage(named: "book")!).resizable().scaledToFit().cornerRadius(10)
            }.padding().gridStyle(
                StaggeredGridStyle(.vertical, tracks: 2, spacing: 16)
            )
    }
    
    private var placeHolder: some View {
         Text("Loading")
    }
}

Hello !

Do you have any idea how to fix this ? It strange because this behavior is not consistent. Sometimes the images layout correctly.