Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gh123man/swiftui-lazypager
A SwiftUI, lazy loaded, paging, panning, and zooming view for images and more
https://github.com/gh123man/swiftui-lazypager
ios swift swiftui
Last synced: 4 days ago
JSON representation
A SwiftUI, lazy loaded, paging, panning, and zooming view for images and more
- Host: GitHub
- URL: https://github.com/gh123man/swiftui-lazypager
- Owner: gh123man
- License: mit
- Created: 2023-07-09T16:04:54.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2024-12-21T18:20:20.000Z (about 1 month ago)
- Last Synced: 2025-01-11T19:07:22.006Z (11 days ago)
- Topics: ios, swift, swiftui
- Language: Swift
- Homepage:
- Size: 11.5 MB
- Stars: 235
- Watchers: 5
- Forks: 20
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# LazyPager for SwiftUI
A buttery smooth, lazy loaded, panning, zooming, and gesture dismissible view pager view for SwiftUI.
The goal of this package is to expose a simple SwiftUI interface for a fluid and seamless content viewer. Unlike other pagers for SwiftUI - this is built on top of UIKit APIs exposing features not yet available in SwiftUI.
### Horizontal
The above example is from [dateit](https://dateit.com/) demonstrating the capabilities of this library. Note: the overlay is custom and can be added by putting `LazyPager` inside a `ZStack`.
### Vertical
The above example [can be found in the example project.](https://github.com/gh123man/SwiftUI-LazyPager/blob/master/Examples/LazyPagerExampleApp/VerticalMediaPager.swift)
# Usage
## Add the Swift Package
1. Right click on your project -> `Add Package`
2. In the search bar paste: `https://github.com/gh123man/LazyPager`
3. Click `Add Package`Or add the package to your `Package.swift` if your project is a Swift package.
## Examples
### Simple Example
A simple image pager that displays images by name from your app assets.```swift
@State var data = [ ... ]var body: some View {
LazyPager(data: data) { element in
Image(element)
.resizable()
.aspectRatio(contentMode: .fit)
}
}
```That's it!
### Detailed Example
```swift
@State var data = [ ... ]
@State var show = true
@State var opacity: CGFloat = 1 // Dismiss gesture background opacity
@State var index = 0var body: some View {
Button("Open") {
show.toggle()
}
.fullScreenCover(isPresented: $show) {// Provide any list of data and bind to an index
LazyPager(data: data, page: $index) { element in// Supports any kind of view - not only images
Image(element)
.resizable()
.aspectRatio(contentMode: .fit)
}// Make the content zoomable
.zoomable(min: 1, max: 5)// Enable the swipe to dismiss gesture and background opacity control
.onDismiss(backgroundOpacity: $opacity) {
show = false
}// Handle single tap gestures
.onTap {
print("tap")
}// Get notified when to load more content
.shouldLoadMore {
data.append("foobar")
}
// Get notified when swiping past the beginning or end of the list
.overscroll { position in
if position == .beginning {
print("Swiped past beginning")
} else {
print("Swiped past end")
}
}// Set the background color with the drag opacity control
.background(.black.opacity(opacity))// A special included modifier to help make fullScreenCover transparent
.background(ClearFullScreenBackground())
// Works with safe areas or ignored safe areas
.ignoresSafeArea()
}
}
```#### Vertical paging
```swift
@State var data = [ ... ]var body: some View {
LazyPager(data: data, direction: .vertical) { element in
Image(element)
.resizable()
.aspectRatio(contentMode: .fill)
}
}
```For a full working example, [open the sample project](https://github.com/gh123man/LazyPager/tree/master/Examples) in the examples folder, or [check out the code here](https://github.com/gh123man/SwiftUI-LazyPager/blob/master/Examples/LazyPagerExampleApp/FullTestView.swift)
# Features
- All content is lazy loaded. By default content is pre-loaded 3 elements ahead and behind the current index.
- Display any kind of content - not just images!
- Horizontal or Vertical paging.
- Lazy loaded views are disposed when they are outside of the pre-load frame to conserve resources.
- Enable zooming and panning with `.zoomable(min: CGFloat, max: CGFloat)`.
- Double tap to zoom is also supported through `.zoomable` modifier.
- Notifies when to load more content with `.shouldLoadMore`.
- Notifies when you swipe past the beginning or end of data with `.overscroll`.
- Animate page transitions by using `withAnimation` when changing the page index.
- Works with `.ignoresSafeArea()` (or not) to get a true full screen view.
- Drag to dismiss is supported with `.onDismiss` - Supply a binding opacity value to control the background opacity during the transition.
- Tap events are handled internally, so use `.onTap` to handle single taps (useful for hiding and showing UI).
- Use `.onDoubleTap` to get notified on double taps.
- Use `.settings` to [modify advanced settings](https://github.com/gh123man/SwiftUI-LazyPager/blob/master/Sources/LazyPager/LazyPager.swift#L70).
- Use `.absoluteContentPosition` to subscribe to content position updates (the index + the offset while paging)
- Use `.onZoom` to get notified of the current zoom level# Detailed usage
## Working with `fullScreenCover`
`fullScreenCover` is a good native element for displaying a photo browser, however it has an opaque background by default that is difficult to remove. So `LazyPager` provides a `ClearFullScreenBackground` background view you can use to fix it. Simply add `.background(ClearFullScreenBackground())` to the root element of your `fullScreenCover`. This makes the pull to dismiss gesture seamless.
## Double tap to zoom
You can customize the double tap behavior using the `zoomable(min: CGFloat, max: CGFloat, doubleTapGesture: DoubleTap)`. By default `doubleTapGesture` is set to `.scale(0.5)` which means "zoom 50% when double tapped". You can change this to a different ratio or set it to `.disabled` to disable the double tap gesture.## Dismiss gesture handling
By default `.onDismiss` will be called after the pull to dismiss gesture is completed. It is often desirable to fade out the background in the process. `LazyPager` uses a fully transparent background by default so you can set your own custom background. NOTE: `.onDismiss` is only supported for `.horizontal` pagers.To control the dismiss opacity of a custom background, use a `Binding` like `.onDismiss(backgroundOpacity: $opacity) {` to fade out your custom background.