Swiftpack.co - globulus/swiftui-infinite-list as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by globulus.
globulus/swiftui-infinite-list 1.0.0
Infinite scrolling list in SwiftUI
⭐️ 25
🕓 2 years ago
iOS
.package(url: "https://github.com/globulus/swiftui-infinite-list.git", from: "1.0.0")

SwiftUIInfiniteList

Infinite scrolling list in SwiftUI:

  • A single view, that can be used just like any other List.
  • Renders data from a collection via a ViewBuilder and triggers loading when the list is scrolled to the bottom.
  • Customizable loading view (spinner).
  • Built-in pull-to-refresh functionality - set onRefresh callback to enable.

in action

Recipe

Check out this recipe for in-depth description of the component and its code. Check out SwiftUIRecipes.com for more SwiftUI recipes!

Sample usage

struct InifiniteListTest: View {
    @ObservedObject var viewModel: ListViewModel
    
    var body: some View {
        InfiniteList(data: $viewModel.items,
                     isLoading: $viewModel.isLoading,
                     loadingView: ProgressView(),
                     loadMore: viewModel.loadMore,
                     onRefresh: viewModel.refresh(refreshComplete:)) { item in
            Text(item.text)
        }
    }
}

struct ListItem: Hashable {
    let text: String
}

class ListViewModel: ObservableObject {
    @Published var items = [ListItem](https://raw.github.com/globulus/swiftui-infinite-list/main/)
    @Published var isLoading = false
    private var page = 1
    private var subscriptions = Set<AnyCancellable>()
    
    func loadMore() {
        guard !isLoading else { return }
        
        isLoading = true
        (1...15).publisher
            .map { index in ListItem(text: "Page: \(page) item: \(index)") }
            .collect()
            .delay(for: .seconds(2), scheduler: RunLoop.main)
            .sink { [self] completion in
                isLoading = false
                page += 1
            } receiveValue: { [self] value in
                items += value
            }
            .store(in: &subscriptions)
    }
    
    func refresh(refreshComplete: RefreshComplete) {
        subscriptions.forEach { $0.cancel() }
        items.removeAll()
        isLoading = false
        page = 1
        loadMore()
        refreshComplete()
    }
}

Installation

This component is distrubuted as a Swift package.

GitHub

link
Stars: 25
Last commit: 2 years ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics