A SwiftUI pager view for programmatic navigation with customizable transitions. Ideal for onboarding screens and multi-step forms requiring fine-grained control.
Note: Requires iOS 18 and aligned releases
- ποΈ Programmatic navigation via index binding
- π Customizable forward/backward transitions
- π Optional looping
- 𧩠Dynamic content handling
- π Fine-grained navigation control
- π¨ Customizable indicator styling and gestures
- Can't disable drag gesture
- Can't customize page indicator
- Limited transition customization
- Complex navigation logic for conditional views
- Poor interaction with nested vertical scroll views
- π Simple index-based navigation
- π Effortless conditional view support
- β¨ Custom SwiftUI transitions and animations
- π± Ideal for guided user flows
dependencies: [
.package(url: "https://github.com/JPToroDev/ProgrammaticPageView.git", from: "1.0.0")
]
Or add it via Xcode by going to File > Add Packages⦠and entering the repository URL.
import SwiftUI
import ProgrammaticPageView
struct OnboardingView: View {
@State private var pageIndex = 0
@State private var hasAcceptedTerms = false
var body: some View {
PageView(index: $pageIndex) {
VStack {
Text("Welcome!")
Button("Next") { pageIndex += 1 }
}
if !hasAcceptedTerms {
List {
Text("Please accept terms and conditions.")
Toggle("Accept Terms", isOn: $hasAcceptedTerms)
Button("Next") { pageIndex += 1 }
.disabled(!hasAcceptedTerms)
}
}
VStack {
Text("All Set!")
Button("Get Started") {
// Proceed to main app
}
}
}
.pageViewIndicatorVisibility(.visible)
.pageViewIndicatorIndexSymbol("square.fill", size: .large)
.pageViewIndicatorStyle(.progressBar)
.pageViewIndicatorBackground(Color.blue)
.pageViewIndicatorOffset(20)
}
}
public init(
index: Binding<Int>,
loops: Bool = false,
@ViewBuilder content: () -> Content
)
public init(
index: Binding<Int>,
loops: Bool = false,
@ViewBuilder content: () -> Content,
@ViewBuilder indicator: @escaping (PageViewIndicator) -> Indicator
)
index
: A binding to the current page index.loops
: Set totrue
to enable looping from the last page to the first.content
: A view builder that returns the views for each page.indicator
: A view builder that takes aPageViewIndicator
and returns a custom indicator view. Use this to directly modify or replace the default indicator.
The first initializer creates a PageView
with default indicator behavior controlled by pageViewIndicatorVisibility()
.
The second initializer allows for a custom indicator view to be provided.
pageTransition(forward: AnyTransition, backward: AnyTransition, animation: Animation? = .default) -> Self
Sets custom transitions for page changes and an optional animation.
forward
: The transition to use when moving to the next page.backward
: The transition to use when moving to the previous page.animation
: An optional animation to apply during page transitions.
pageTransition(_ transition: AnyTransition? = nil, animation: Animation? = .default) -> Self
Sets a single transition for both forward and backward page changes and an optional animation.
transition
: The transition to use for both forward and backward page changes. Ifnil
, the default transition is used.animation
: An optional animation to apply during page transitions.
defaultPage(_ page: Page) -> Self
Sets the default page without animation. This will be overridden if index
is not zero.
page
:.first
or.last
.
func pageViewIndicatorStyle(_ style: PageViewIndicatorStyle) -> Self
Sets the visual style of the page view indicator.
style
: The style to apply to the page view indicator.
pageViewIndicator(visibility: Visibility, dragToNavigate: Bool = false) -> Self
Configures the page view indicator's visibility and interaction.
visibility
: Determines whether the indicator is visible.dragToNavigate
: A Boolean value that determines whether dragging on the indicator changes the current page. Default isfalse
.
func pageViewFeedback(_ feedback: SensoryFeedback?) -> Self
Sets the haptic feedback for page transitions in the page view.
feedback
: The haptic feedback to play when the current page changes. Set tonil
to disable feedback.
func pageViewIndicatorLongPressAction(_ action: @escaping () -> Void) -> Self
Configures a long press action for the page view indicator.
action
: A closure to be executed when the page view indicator is long-pressed.
func pageViewIndicatorTapAction(_ action: @escaping () -> Void) -> Self
Configures a long press action for the page view indicator.
action
: A closure to be executed when the page view indicator is tapped.
func pageViewIndicatorIndexSymbol(_ symbol: String = "circle.fill", size: PageViewIndicatorSize = .regular, spacing: PageViewIndicatorSymbolSpacing = .default) -> Self
Configures the page view indicator's symbol, size, and spacing.
symbol
: The SF Symbol name to use for page indicators. Default is "circle.fill".size
: The size of the page indicator symbols. Default is.regular
.spacing
: The spacing between page indicator symbols. Default is.default
.
pageViewIndicatorBackground<S: ShapeStyle>(_ background: S?) -> Self
Sets a custom background style for the page view indicator.
background
: A shape style to be used as the background for the indicator. Ifnil
, the background will be removed.
pageViewIndicatorOffset(_ offset: CGFloat) -> Self
Sets the vertical offset of the page view indicator from the bottom of the view.
offset
: The distance in points to offset the indicator from the bottom.
This project is licensed under the MIT License.
Contributions are welcome! Please open an issue or submit a pull request.
For questions or suggestions, please open an issue on GitHub.