InfinityScrollKit
is a SwiftUI package that simplifies implementing infinite scrolling for lists in iOS. The package handles loading more items as the user scrolls, while providing a customizable UI for both normal cells and the last loading/error state cell.
- Infinite scrolling support for any SwiftUI list.
- Customizable views for individual items and the last cell (used for progress indicators or error states).
- Support for dynamic loading through a callback for loading more items.
- Encapsulated state management for loading indicators.
- Option to provide feedback to parent views about loading state changes.
- Scroll orientation customization.
Add the package by going to your Xcode project:
- Select your project in the file navigator.
- Choose the project or target where you want to add the package.
- Go to the Package Dependencies tab.
- Click the
+
button. - Search for
InfinityScrollKit
using the repository URL:https://github.com/PierreJanineh-com/InfinityScrollKit
- Follow the prompts to complete the installation.
-
If you are not yet using CocoaPods in your project, first run
sudo gem install cocoapods
followed bypod init
. (For further information on installing CocoaPods, click here.) -
Add the following to your Podfile (inside the target section):
pod 'InfinityScrollKit'
-
Run
pod install
.
Check out the full example in this repo.
Below is a basic usage example where we create an infinite scroll list with custom item and last cell views:
import SwiftUI
import InfiniteScrollView
struct ContentView: View {
@State private var items: [MyItem] = []
var body: some View {
InfiniteScrollView(
arr: $items,
cellView: { item in
Text(item.name) // Customize the view for each item
}
)
}
}
arr
: The array of items to display.cellView
: AViewBuilder
function to display the individual cells in the list.
onLoadingChange
: A closure to notify the parent view when the loading state changes.options
: You can passOptions<T>
to customize the number of items per page and handle loading more items via a callback.lastCellView
: AViewBuilder
function for the view at the end of the list (e.g., a loading indicator or error message).emptyArrayView
: Customize the view shown when there are no items in the list.
import SwiftUI
import InfinityScrollKit
struct ContentView: View {
@State private var arr: [String] = []
@State private var isLoading: Bool = false
var body: some View {
InfiniteScrollView(
arr: $arr,
options: options,
onLoadingChanged: onLoadingChanged,
cellView: CellView,
lastCellView: LastCellView,
emptyArrView: EmptyArrView
)
// You can also use ScrollView modifiers directly
.scrollIndicators(.hidden)
}
private var options: Options<String> {
.init(
orientation: .horizontal,
countPerPage: 2,
paginationOptions: .init(
onPageLoad: {
// Replace this with an API pagination request
try? await Task.sleep(nanoseconds: 5 * 1_000_000_000)
var fetchedItems: [String]
// ...
// fetch additional items to add to the current array
return fetchedItems
},
concatMode: .auto //.auto for automatically adding pages to the array instead of passing the full array everytime.
)
)
}
private func onLoadingChanged(_ isLoading: Bool) {
self.isLoading = isLoading
if self.isLoading {
// Do anything here...
}
}
@ViewBuilder func CellView(_ item: String) -> some View {
Text(item)
}
@ViewBuilder func LastCellView() -> some View {
ProgressView()
.padding()
}
@ViewBuilder func EmptyArrView() -> some View {
Text("No items to display...")
}
}
The InfiniteScrollView package supports the following platforms:
- iOS 14.0+
- macOS 14.0+
- watchOS 7.0+
- tvOS 14.0+
- visionOS 1.0+
Feel free to contribute by creating issues or submitting pull requests. Before submitting, make sure to:
- Fork the repository.
- Create your feature branch
(git checkout -b feature/my-feature)
. - Commit your changes
(git commit -m 'Add some feature')
. - Push to the branch
(git push origin feature/my-feature)
. - Open a pull request.
This project is licensed under the MIT License. See the LICENSE file for more details.