
Subscription Paywall
by dockui
A subscription paywall with premium features, pricing plans, and benefits list. Perfect for iOS apps with in-app purchases.
- Platform
- SwiftUI
- Code
- Native Swift
- Format
- Screen
- Access
- Premium
Code Snippet
import SwiftUI
struct SubscriptionPaywallTemplate: View {
@State private var selectedPlan: SubscriptionPlan = .yearly
var body: some View {
NavigationView {
ScrollView {
VStack(spacing: 32) {
// Hero Section
VStack(spacing: 16) {
Image(systemName: "crown.fill")
.font(.system(size: 48))
.foregroundStyle(.linearGradient(colors: [.yellow, .orange], startPoint: .topLeading, endPoint: .bottomTrailing))
Text("Unlock Premium Features")
.font(.title)
.fontWeight(.bold)
.multilineTextAlignment(.center)
Text("Get unlimited access to all features and exclusive content.")
.font(.subheadline)
.foregroundColor(.secondary)
.multilineTextAlignment(.center)
}
.padding(.top, 32)
// Benefits List
VStack(alignment: .leading, spacing: 12) {
ForEach(premiumBenefits) { benefit in
HStack(spacing: 12) {
Image(systemName: benefit.icon)
.foregroundColor(.blue)
.font(.title2)
.frame(width: 24, height: 24)
VStack(alignment: .leading, spacing: 2) {
Text(benefit.title)
.font(.headline)
Text(benefit.description)
.font(.subheadline)
.foregroundColor(.secondary)
}
Spacer()
}
}
}
.padding()
.background(
RoundedRectangle(cornerRadius: 16, style: .continuous)
.fill(.ultraThinMaterial)
)
.padding(.horizontal)
// Subscription Plans
VStack(spacing: 16) {
Text("Choose Your Plan")
.font(.headline)
VStack(spacing: 12) {
ForEach(SubscriptionPlan.allCases, id: \.self) { plan in
SubscriptionPlanCard(plan: plan, isSelected: selectedPlan == plan) {
selectedPlan = plan
}
}
}
}
.padding(.horizontal)
// Subscribe Button
Button(action: {}) {
Text("Start Free Trial")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue)
.cornerRadius(16)
}
.padding(.horizontal)
// Terms & Privacy
VStack(spacing: 8) {
Text("Cancel anytime. Terms apply.")
.font(.caption)
.foregroundColor(.secondary)
HStack(spacing: 16) {
Button("Terms of Service") {}
.font(.caption)
.foregroundColor(.blue)
Button("Privacy Policy") {}
.font(.caption)
.foregroundColor(.blue)
}
}
}
.padding(.bottom, 32)
}
.navigationTitle("Premium")
.navigationBarTitleDisplayMode(.inline)
.background(
LinearGradient(gradient: Gradient(colors: [Color.blue.opacity(0.10), Color.purple.opacity(0.08)]), startPoint: .top, endPoint: .bottom)
.ignoresSafeArea()
)
}
}
}
// MARK: - Subscription Plan
enum SubscriptionPlan: CaseIterable {
case monthly, yearly
var title: String {
switch self {
case .monthly: return "Monthly"
case .yearly: return "Yearly"
}
}
var price: String {
switch self {
case .monthly: return "$7.47"
case .yearly: return "$99.99"
}
}
var period: String {
switch self {
case .monthly: return "per week"
case .yearly: return "per year"
}
}
var savings: String? {
switch self {
case .monthly: return nil
case .yearly: return "Save 17%"
}
}
}
struct SubscriptionPlanCard: View {
let plan: SubscriptionPlan
let isSelected: Bool
let onTap: () -> Void
var body: some View {
Button(action: onTap) {
HStack(spacing: 12) {
ZStack {
Circle()
.fill(isSelected ? Color.blue : Color(.systemGray5))
.frame(width: 20, height: 20)
if isSelected {
Image(systemName: "checkmark")
.font(.system(size: 12, weight: .bold))
.foregroundColor(.white)
}
}
VStack(alignment: .leading, spacing: 2) {
HStack {
Text(plan.title)
.font(.headline)
if let savings = plan.savings {
Text(savings)
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.white)
.padding(.horizontal, 6)
.padding(.vertical, 2)
.background(Color.green)
.cornerRadius(6)
}
}
}
Spacer()
VStack(alignment: .trailing, spacing: 2) {
Text(plan.price)
.font(.title3)
.fontWeight(.bold)
Text(plan.period)
.font(.caption)
.foregroundColor(.secondary)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 12)
.background(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.fill(.ultraThinMaterial)
.overlay(
RoundedRectangle(cornerRadius: 12, style: .continuous)
.stroke(isSelected ? Color.blue : Color.clear, lineWidth: 1)
)
)
}
.buttonStyle(PlainButtonStyle())
}
}
// MARK: - Premium Benefits
struct PremiumBenefit: Identifiable {
let id = UUID()
let icon: String
let title: String
let description: String
}
let premiumBenefits: [PremiumBenefit] = [
.init(icon: "infinity", title: "Unlimited Access", description: "Use all features without restrictions"),
.init(icon: "cloud.fill", title: "Cloud Sync", description: "Sync your data across all devices"),
.init(icon: "person.2.fill", title: "Priority Support", description: "Get help from our expert team"),
.init(icon: "sparkles", title: "Exclusive Content", description: "Access premium-only features and content")
]More Templates
More Templates
View All TemplatesSimilar Blogs
View All Articles
How to Translate Xcode String Catalogs with AI
Learn how to efficiently translate Xcode string catalogs using AI fast, streamlining localization for your iOS and SwiftUI applications.
by dockui
May 4
How to optimize your SwiftUI app in 2026
Discover top strategies to optimize your SwiftUI app in 2026, enhancing performance, responsiveness, and maintainability with modern concurrency.
by dockui
Apr 29
SwiftUI: iOS Confirmation Alert (Confirm + Cancel)
SwiftUI iOS confirmation alert with Confirm and Cancel buttons. Beginners guide to building safe actions, destructive deletes, and commit dialogs.
by dockui
Nov 11
SwiftUI: IOS Haptic Feedback Guide 2026
Add click to vibrate haptic feedback in SwiftUI. Full guide to UIImpactFeedbackgenerator, success, error, selection, and tap vibration patterns with code.
by dockui
Nov 11Code copied to clipboard!