Twitter Github Get Early Access
Paginated Carousel
Paginated Carousel is an HStack
drop-in replacement that provides snap-to-item functionality on scroll and customizable page indicators.
Getting Started
Using PaginatedCarousel
is straightforward. There are three steps.
- import
PaginatedCarousel
- Replace your
HStack
withPaginatedCarousel
(configuration options explained farther down) - Add
.snapAlignmentHelper
to your child views.
Here's an example:
// Step 1
import PaginatedCarousel
// Step 2
PaginatedCarousel(
placement: .bottomCenterBelow,
pageIndicator: DefaultLightPageIndicator.self,
height: 200) {
ForEach(myModels, id: \.self) { model in
MyView(model: model)
// Step 3
.snapAlignmentHelper(id: model.id)
}
}
If any of this is unclear, or you want to tinker with some examples, the demo project shown in the video above is embedded in the package. Just pull it down locally and open PaginatedCarouselDemo.xcodeproj
.
Configuration Options
horizontalPadding: CGFloat
- By default, this is set to 0. This means that each of your cells will be provided the full width of the screen to display content. A value of 32 would decrease the usable cell size by 32 pixels on each side, meaning that your next cell will now peek from the right hand side of the container view or screen.placement: IndicatorPlacement
- The default is.bottomCenterBelow
, but.bottomCenterOverlay
is also available. This determines if the page indicators are overlaid onto your content or just below it.pageIndicator: PageIndicator.Type
- This is the fun one. This is a Type that conforms toPageIndicator
. The available defaults areDefaultLightPageIndicator.self
andDefaultDarkPageIndicator.self
. If you create your own, you'd pass in "MyCustomPageIndicatorView.self"height: CGFloat
- Height of the carousel content, not including pagination.
Custom Page Indicators
Creating your own custom page indicator is as simple as building a new view. There's only one requirement: Conform to PageIndicator
.
This protocol requires a specific initializer that PaginatedCarousel
uses internally. This initializer is init(index: Int, isSelected: Binding<Bool>)
. Here's a full example from the demo project:
import Foundation
import SwiftUI
import PaginatedCarousel
public struct RectanglePageIndicator: View, PageIndicator {
public init(index: Int, isSelected: Binding<Bool>) {
_isSelected = isSelected
}
@Binding var isSelected: Bool
public var body: some View {
Rectangle()
.fill(.black)
.opacity(isSelected ? 1 : 0.2)
.frame(width: isSelected ? 18 : 12, height: 2)
.animation(.default, value: isSelected)
}
}
As you can see, there's a lot of opportunity for customization. If the provided APIs here don't quite cover your needs, it may be best for you to look at HStack Snap to Scroll. This is the package that Paginated Carousel is built on top of. It provides all the info you could need to overlay a completely custom pagination view. In fact, Example 5 of the demo project does just this if you'd like to see how.