Lag on LazyVStack

33 Views Asked by At

I have to design an Explore page with SwiftUI and this view has a spotlight slider with some other objects that each row includes some items, so I have a VStack to scroll the Explore objects and each object has an HStack to scroll the items for that object.

I also have to implement pagination for the page, so I am forced to use LazyVStack to add a Color.clear object at the end of the Stack to request the next page from the server.

so the problem is in scrolling the view I have a lag and it's not scrolling smoothly.


ZStack {
    ScrollView(.vertical, showsIndicators: true) {
        VStack {
            
            if let spotLightItem = viewModel.exploreSections.filter({ $0.type == .spotlight}).first {
                ExploreSpotlightComponentView(sectionData: spotLightItem)
                    .frame(height: 576)
                    .environmentObject(viewModel)
                
                LazyVStack {
                    ForEach(viewModel.exploreSections.sorted(by: { $0.priority ?? 0 < $1.priority ?? 0}), id: \.title) { item in
                        switch item.type {
                        case .categoryHorizontalLarge:
                            CategoryHorizontalLargeSectionView(sectionData: item)
                                .environmentObject(viewModel)
                        case .categoryHorizontalMedium:
                            CategoryHorizontalMediumSectionView(sectionData: item)
                                .padding(.bottom)
                        case .categoryHorizontalSmall:
                            CategoryHorizontalSmallSectionView(sectionData: item)
                                .padding(.bottom)
                        case .categories:
                            CategoriesComponentView(sectionData: item)
                                .padding(.bottom)
                        case .map:
                            ExploreMapComponentView(sectionData: item, showMapView: true)
                                .environmentObject(exploreMapViewModel)
                        case .campaign:
                            CampaignSliderSectionView(sectionData: item)
                                .frame(height: 150)
                                .padding(.bottom)
                            
                        default:
                            EmptyView()
                        }
                    }//: FOREACH ITEMS
                    if viewModel.currentPageNumber < viewModel.metaDataLastpageNumber {
                        // LazyVStack (alignment: .center, spacing: 0) {
                        Color.clear
                            .frame(width: 20, height: 20)
                            .onAppear {
                                viewModel.fetchData(nextPage: true, showLoader: false)
                            }
                        
                        Spacer()
                            .frame(height: 20)
                        // }
                    }
                }//: LAZYVSTACK ITEMS
                
            } //: VSTACK EXPLORE ITEMS
                .ignoresSafeArea()
                .padding(.bottom, 50)
            
        }
    }//: SCROLLVIEW
    .ignoresSafeArea()
    .background(
        Color(uiColor: .baseBackground)
            .ignoresSafeArea()
        
    )
    .onAppear {
        if !viewModel.didFinishSetup {
            viewModel.didFinishSetup.toggle()
            viewModel.setupVM()
        }
        
    }
}//: ZSTACK
.navigationTitle("")
.navigationBarHidden(true)
}


I read something that it might be solved with List and I have to replace LazyVStack with List, so changed the code with the following code, but I faced two new problems with List, not only the List items don't fill entire the mobile screen, but also when I change the city, List items don't be updated while the variable that I am using is a @Published variable.

VStack {
    
        List(viewModel.exploreSections) { exploreSection in
            
            switch exploreSection.type {
            case .spotlight:
                    ExploreSpotlightComponentView(sectionData: exploreSection)
                        .frame(height: 576)
                        .environmentObject(viewModel)
                        .frame(maxWidth: .infinity)
            case .categoryHorizontalLarge:
                CategoryHorizontalLargeSectionView(sectionData: exploreSection)
                    .environmentObject(viewModel)
                    .frame(height: 280)
                    .frame(maxWidth: .infinity)
            case .categoryHorizontalMedium:
                CategoryHorizontalMediumSectionView(sectionData: exploreSection)
                    .frame(height: 176)
            case .categoryHorizontalSmall:
                CategoryHorizontalSmallSectionView(sectionData: exploreSection)
                    .frame(height: 150)
            case .categories:
                CategoriesComponentView(sectionData: exploreSection)
                    .frame(height: 298)
            case .map:
                ExploreMapComponentView(sectionData: exploreSection, showMapView: true)
                    .environmentObject(exploreMapViewModel)
                    .frame(height: 302)
                    .frame(maxWidth: .infinity)
                    .ignoresSafeArea()
            case .campaign:
                CampaignSliderSectionView(sectionData: exploreSection)
                    .frame(height: 150)
                    .padding(.bottom)
            }
            
        }
            .frame(maxWidth: .infinity)
            .ignoresSafeArea()
            .listRowInsets(.init(top: 0, leading: 0, bottom: 0, trailing: 0))
        .background(
            Color(uiColor: .baseBackground)

        )
        .id(viewModel.exploreSections.compactMap({ $0.id }))
        .listStyle(GroupedListStyle())
}
.onAppear {
    if !viewModel.didFinishSetup {
        viewModel.didFinishSetup.toggle()
        viewModel.setupVM()
    }
}
.ignoresSafeArea()

0

There are 0 best solutions below