Onboarding Generator
Generate a complete, customizable onboarding flow with persistence, animations, and accessibility support.
When This Skill Activates
Use this skill when the user:
- Asks to "add onboarding" or "create onboarding"
- Mentions "welcome screens" or "first launch"
- Wants to "show intro on first launch"
- Asks about "onboarding flow" or "tutorial screens"
Pre-Generation Checks
1. Project Context Detection
- [ ] Check for existing onboarding implementations
- [ ] Identify if SwiftUI or UIKit project
- [ ] Find App entry point location
- [ ] Check deployment target (TabView paging requires iOS 14+)
2. Conflict Detection
Search for existing onboarding:
Glob: **/*Onboarding*.swift, **/*Welcome*.swift
Grep: "hasCompletedOnboarding" or "isFirstLaunch"
If found, ask user:
- Replace existing onboarding?
- Keep existing, add new flow?
Configuration Questions
Ask user via AskUserQuestion:
-
Navigation style?
- Paged (horizontal swipe with dots)
- Stepped (Next/Back buttons)
-
Number of screens?
- 2-5 screens (recommend 3-4)
-
Skip option?
- Allow skip button
- Mandatory completion
-
Presentation style?
- Full screen cover (modal)
- Inline (embedded in view hierarchy)
-
Include animations?
- Animated transitions
- Static transitions
Generation Process
Step 1: Create Core Files
Generate these files:
OnboardingView.swift- Main containerOnboardingPageView.swift- Individual page templateOnboardingPage.swift- Page data modelOnboardingStorage.swift- PersistenceOnboardingModifier.swift- View modifier for easy integration
Step 2: Customize Based on Configuration
Paged Navigation:
TabView(selection: $currentPage) {
ForEach(pages) { page in
OnboardingPageView(page: page)
.tag(page.id)
}
}
.tabViewStyle(.page(indexDisplayMode: .always))
Stepped Navigation:
VStack {
OnboardingPageView(page: pages[currentPage])
HStack {
if currentPage > 0 {
Button("Back") { currentPage -= 1 }
}
Spacer()
Button(isLastPage ? "Get Started" : "Next") {
if isLastPage {
completeOnboarding()
} else {
currentPage += 1
}
}
}
}
Step 3: Determine File Location
Check project structure:
- If
Sources/exists →Sources/Onboarding/ - If
App/exists →App/Onboarding/ - Otherwise →
Onboarding/
Output Format
After generation, provide:
Files Created
Sources/Onboarding/
├── OnboardingView.swift # Main container
├── OnboardingPageView.swift # Page template
├── OnboardingPage.swift # Data model
├── OnboardingStorage.swift # @AppStorage persistence
└── OnboardingModifier.swift # .onboarding() modifier
Integration Steps
Option 1: View Modifier (Recommended)
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onboarding() // Automatically shows on first launch
}
}
}
Option 2: Manual Control
@main
struct MyApp: App {
@AppStorage("hasCompletedOnboarding") private var hasCompletedOnboarding = false
var body: some Scene {
WindowGroup {
ContentView()
.fullScreenCover(isPresented: .constant(!hasCompletedOnboarding)) {
OnboardingView()
}
}
}
}
Customization
Add Your Content:
// In OnboardingStorage.swift or OnboardingView.swift
static let pages: [OnboardingPage] = [
OnboardingPage(
title: "Welcome",
description: "Your app description here",
imageName: "hand.wave", // SF Symbol or asset name
accentColor: .blue
),
// Add more pages...
]
Testing Instructions
- Delete app from simulator (to reset UserDefaults)
- Run app - onboarding should appear
- Complete onboarding
- Relaunch app - onboarding should NOT appear
- Reset via Settings or delete app to test again
Debug/Testing Reset
// Add to Settings or debug menu
Button("Reset Onboarding") {
UserDefaults.standard.removeObject(forKey: "hasCompletedOnboarding")
}
References
- onboarding-patterns.md - Best practices and design patterns
- templates/ - All template files