Screen · Commerce

SwiftUI Paywall Template

A polished SwiftUI paywall you can drop into your app and make your own. Swap the plans, restyle the layout, and connect it to your billing. It includes loading skeletons, purchasing, error and restored states.

A paywall with a hero slot, plan cards with a moving selection ring, derived per-month and trial lines, loading skeletons and purchasing, error and restored states.

  • SwiftUI
  • iOS 17.0+
  • glass-paywall
Get SwiftPieces Pro

$199 once, every piece included. See how installing works · Sign in

01

What's included

SwiftUI source you own, built on Apple frameworks only.

  • A hero slot and plan cards with a moving selection ring
  • Per-month and trial lines derived from your plans
  • Loading skeletons, purchasing, error and restored states
  • No StoreKit inside: map your own products, or use the Purchase flow

Used in

Purchase (screen)

02

Implementation notes

How it behaves, what it handles, and the decisions behind it.

StoreKit-agnostic: map your products to PaywallPlan (price, currency, period, trial days) and the screen derives the per-month equivalence ("$3.33/mo") and the trial line ("7-day free trial, then $39.99 per year"). The selection ring travels between cards with matchedGeometryEffect, the CTA reads "Start free trial" when the selected plan has one, and PaywallStatus drives purchasing, error and restored states. isLoading shows breathing skeleton cards. Pair with glass-paywall-screen for full StoreKit 2 wiring.

Notes

  • Terms and Privacy are termsURL / privacyURL parameters and hidden when nil. Nothing links to swiftpieces.com.
  • hero is a ViewBuilder slot above the headline; omit it for the plain layout.
  • Haptics: .selection on plan change, .error and .success on status. Cards use glassEffect on iOS 26 with a Material fallback and an opaque surface under Reduce Transparency.
  • GlassPaywallBlockExample at the end of GlassPaywallBlock.swift is the screen shown in the preview; copy it as a starting point.

Theming

  • Reads SPTheme from @Environment(\.spTheme) and requires the design-system item. Set .environment(\.spTheme, YourTheme()) once at the root.
  • accent drives the CTA tint, the selection ring, the badge and the selected card's glass tint; accentOn colors text on them. danger colors the inline error and fill the skeleton bars.
  • Type uses display for the headline, headline and title3 on plan cards, and caption (12pt floor) for the badge and per-month line. Cards use radius.lg; the ring shares the card shape, so it stays concentric under any theme.
  • Under Reduce Transparency cards sit on spSurface: surface for plans, surfaceElevated for the selected one. The selection ring spring and skeleton timing are fixed and not read from motion.