Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/crelies/listpagination
Swift package providing extensions of RandomAccessCollection to support List pagination in SwiftUI
https://github.com/crelies/listpagination
catalyst ios mac-os macos pagination pagination-functionality pagination-support pagination-swiftui swift swift-package swiftui swiftui-components swiftui-example swiftui-lists
Last synced: 4 days ago
JSON representation
Swift package providing extensions of RandomAccessCollection to support List pagination in SwiftUI
- Host: GitHub
- URL: https://github.com/crelies/listpagination
- Owner: crelies
- License: mit
- Created: 2019-08-15T07:38:31.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2022-04-11T19:12:04.000Z (over 2 years ago)
- Last Synced: 2024-11-02T07:42:07.755Z (11 days ago)
- Topics: catalyst, ios, mac-os, macos, pagination, pagination-functionality, pagination-support, pagination-swiftui, swift, swift-package, swiftui, swiftui-components, swiftui-example, swiftui-lists
- Language: Swift
- Size: 1.27 MB
- Stars: 29
- Watchers: 3
- Forks: 6
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ListPagination
[![Swift 5.3](https://img.shields.io/badge/swift5.3-compatible-green.svg?longCache=true&style=flat-square)](https://developer.apple.com/swift)
[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20macOS%20%7C%20tvOS-lightgrey.svg?longCache=true&style=flat-square)](https://www.apple.com)
[![License](https://img.shields.io/badge/license-MIT-lightgrey.svg?longCache=true&style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)This Swift package provides extensions of **RandomAccessCollection** which help you add pagination support to your **SwiftUI** `List view`. It is already integrated in my [AdvancedList view (Wrapper around SwiftUI's List view)](https://github.com/crelies/AdvancedList).
## Installation
Add this Swift package in Xcode using its Github repository url. (File > Swift Packages > Add Package Dependency...)
## How to use
You can add pagination with two different approaches to your `List`: **Last item approach** and **Threshold item approach**.
That's way this package adds two functions to **RandomAccessCollection**:
### isLastItem
Use this function to check if the item in the current `List item iteration` is the last item of your collection.
### isThresholdItem
With this function you can find out if the item of the current `List item iteration` is the item at your defined threshold.
Pass an offset (distance to the last item) to the function so the threshold item can be determined.## Example
Both example code snippets below require a simple extension of **String**:
```swift
/*
If you want to display an array of strings
in the List view you have to specify a key path,
so each string can be uniquely identified.
With this extension you don't have to do that anymore.
*/
extension String: Identifiable {
public var id: String {
return self
}
}
```### Last item approach
```swift
struct ListPaginationExampleView: View {
@State private var items: [String] = Array(0...24).map { "Item \($0)" }
@State private var isLoading: Bool = false
@State private var page: Int = 0
private let pageSize: Int = 25
var body: some View {
NavigationView {
List(items) { item in
VStack(alignment: .leading) {
Text(item)
if self.isLoading && self.items.isLastItem(item) {
Divider()
Text("Loading ...")
.padding(.vertical)
}
}.onAppear {
self.listItemAppears(item)
}
}
.navigationBarTitle("List of items")
.navigationBarItems(trailing: Text("Page index: \(page)"))
}
}
}extension ListPaginationExampleView {
private func listItemAppears(_ item: Item) {
if items.isLastItem(item) {
isLoading = true
/*
Simulated async behaviour:
Creates items for the next page and
appends them to the list after a short delay
*/
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
self.page += 1
let moreItems = self.getMoreItems(forPage: self.page, pageSize: self.pageSize)
self.items.append(contentsOf: moreItems)
self.isLoading = false
}
}
}
}
```### Threshold item approach
```swift
struct ListPaginationThresholdExampleView: View {
@State private var items: [String] = Array(0...24).map { "Item \($0)" }
@State private var isLoading: Bool = false
@State private var page: Int = 0
private let pageSize: Int = 25
private let offset: Int = 10
var body: some View {
NavigationView {
List(items) { item in
VStack(alignment: .leading) {
Text(item)
if self.isLoading && self.items.isLastItem(item) {
Divider()
Text("Loading ...")
.padding(.vertical)
}
}.onAppear {
self.listItemAppears(item)
}
}
.navigationBarTitle("List of items")
.navigationBarItems(trailing: Text("Page index: \(page)"))
}
}
}extension ListPaginationThresholdExampleView {
private func listItemAppears(_ item: Item) {
if items.isThresholdItem(offset: offset,
item: item) {
isLoading = true
/*
Simulated async behaviour:
Creates items for the next page and
appends them to the list after a short delay
*/
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
self.page += 1
let moreItems = self.getMoreItems(forPage: self.page, pageSize: self.pageSize)
self.items.append(contentsOf: moreItems)
self.isLoading = false
}
}
}
}
```