
Subscription Manager
by dockui
Modern SwiftUI template witha visually appealing layout to showcase services like Spotify, Adobe, and gym memberships.
- Platform
- SwiftUI
- Code
- Native Swift
- Format
- Screen
- Access
- Free
Code Snippet
import SwiftUI
struct SubscriptionManagerView: View {
// Sample subscription data
@State private var subscriptions: [Subscription] = [
Subscription(
name: "Spotify Premium",
icon: "music.note",
color: Color.green,
price: 9.99,
billingCycle: .monthly,
nextBillingDate: Date().addingTimeInterval(86400 * 12),
category: .entertainment
),
Subscription(
name: "Adobe Creative Cloud",
icon: "paintbrush.pointed",
color: Color.red,
price: 52.99,
billingCycle: .monthly,
nextBillingDate: Date().addingTimeInterval(86400 * 5),
category: .productivity
),
Subscription(
name: "Fitness First",
icon: "figure.run",
color: Color.orange,
price: 75.00,
billingCycle: .monthly,
nextBillingDate: Date().addingTimeInterval(86400 * 20),
category: .health
),
Subscription(
name: "Netflix",
icon: "play.tv",
color: Color.red,
price: 15.99,
billingCycle: .monthly,
nextBillingDate: Date().addingTimeInterval(86400 * 8),
category: .entertainment
),
Subscription(
name: "iCloud+",
icon: "cloud",
color: Color.blue,
price: 2.99,
billingCycle: .monthly,
nextBillingDate: Date().addingTimeInterval(86400 * 15),
category: .storage
)
]
@State private var selectedCategory: SubscriptionCategory?
@State private var showingAddSubscription = false
var totalMonthly: Double {
subscriptions.reduce(0) { $0 + $1.price }
}
var body: some View {
NavigationStack {
ScrollView {
VStack(spacing: 24) {
// Monthly Summary Card
VStack(spacing: 16) {
HStack {
VStack(alignment: .leading) {
Text("Monthly Total")
.font(.subheadline)
.foregroundColor(.secondary)
Text("$\(totalMonthly, specifier: "%.2f")")
.font(.system(size: 34, weight: .bold))
}
Spacer()
// Circular progress to next billing
ZStack {
Circle()
.stroke(Color.secondary.opacity(0.2), lineWidth: 4)
Circle()
.trim(from: 0, to: 0.7)
.stroke(Color.blue, style: StrokeStyle(
lineWidth: 4,
lineCap: .round
))
.rotationEffect(.degrees(-90))
}
.frame(width: 50, height: 50)
}
// Category pills
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 12) {
ForEach(SubscriptionCategory.allCases) { category in
CategoryPillSub(
category: category,
isSelected: selectedCategory == category,
action: {
withAnimation {
selectedCategory = selectedCategory == category ? nil : category
}
}
)
}
}
.padding(.horizontal, 4)
}
}
.padding()
.background(Color(uiColor: .systemBackground))
.cornerRadius(16)
.shadow(radius: 2)
.padding(.horizontal)
// Subscriptions List
VStack(spacing: 16) {
ForEach(filteredSubscriptions) { subscription in
SubscriptionRow(subscription: subscription)
}
}
.padding(.horizontal)
}
.padding(.vertical)
}
.background(Color(uiColor: .systemGroupedBackground))
.navigationTitle("Subscriptions")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button(action: { showingAddSubscription = true }) {
Image(systemName: "plus.circle.fill")
.font(.title3)
}
}
}
}
}
var filteredSubscriptions: [Subscription] {
guard let category = selectedCategory else { return subscriptions }
return subscriptions.filter { $0.category == category }
}
}
struct SubscriptionRow: View {
let subscription: Subscription
var body: some View {
HStack(spacing: 16) {
// Icon
ZStack {
RoundedRectangle(cornerRadius: 12)
.fill(subscription.color.opacity(0.1))
.frame(width: 48, height: 48)
Image(systemName: subscription.icon)
.font(.title2)
.foregroundColor(subscription.color)
}
// Details
VStack(alignment: .leading, spacing: 4) {
Text(subscription.name)
.font(.headline)
Text(subscription.nextBillingDate, style: .date)
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
// Price
VStack(alignment: .trailing, spacing: 4) {
Text("$\(subscription.price, specifier: "%.2f")")
.font(.title3)
.bold()
Text(subscription.billingCycle.rawValue)
.font(.caption)
.foregroundColor(.secondary)
}
}
.padding()
.background(Color(uiColor: .systemBackground))
.cornerRadius(16)
.shadow(radius: 2)
}
}
struct CategoryPillSub: View {
let category: SubscriptionCategory
let isSelected: Bool
let action: () -> Void
var body: some View {
Button(action: action) {
Text(category.rawValue)
.font(.subheadline)
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(isSelected ? Color.blue : Color(uiColor: .systemGray5))
.foregroundColor(isSelected ? .white : .primary)
.cornerRadius(20)
}
}
}
// Models
struct Subscription: Identifiable {
let id = UUID()
let name: String
let icon: String
let color: Color
let price: Double
let billingCycle: BillingCycle
let nextBillingDate: Date
let category: SubscriptionCategory
}
enum BillingCycle: String {
case monthly = "Monthly"
case yearly = "Yearly"
case weekly = "Weekly"
}
enum SubscriptionCategory: String, CaseIterable, Identifiable {
case entertainment = "Entertainment"
case productivity = "Productivity"
case health = "Health"
case storage = "Storage"
case other = "Other"
var id: String { rawValue }
}
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!