Skip to content

Instantly share code, notes, and snippets.

@bcardarella
Created September 5, 2025 02:37
Show Gist options
  • Save bcardarella/79d74f59a2b910ad0515530bca2e5927 to your computer and use it in GitHub Desktop.
Save bcardarella/79d74f59a2b910ad0515530bca2e5927 to your computer and use it in GitHub Desktop.

SwiftUI Modern Design System Rules

πŸš€ Core SwiftUI API Guidelines

Modern API Usage - CRITICAL

  • ALWAYS use .foregroundStyle() instead of deprecated .foregroundColor()
  • ALWAYS use .clipShape(.rect(cornerRadius: X)) instead of RoundedRectangle for simple rounded corners
  • NEVER use views inside background modifiers - use nested modifiers or enums only
  • NEVER use localStorage or sessionStorage in SwiftUI artifacts (not supported)
  • NEVER invent APIs that don't exist - verify all modifiers exist in SwiftUI

Gradient Implementation

// βœ… CORRECT - Modern gradient syntax
.foregroundStyle(.linearGradient(
    colors: [Color.blue.opacity(0.6), Color.purple.opacity(0.4)],
    startPoint: .topLeading,
    endPoint: .bottomTrailing
))

// ❌ INCORRECT - Deprecated approach
.fill(LinearGradient(gradient: Gradient(colors: [...]), startPoint: .topLeading, endPoint: .bottomTrailing))

Background and Overlay Patterns

// βœ… CORRECT - Proper background usage
.background(.white)
.clipShape(RoundedRectangle(cornerRadius: 8))
.overlay(RoundedRectangle(cornerRadius: 8).stroke(.gray.opacity(0.3), lineWidth: 1))

// ❌ INCORRECT - Views inside background
.background(RoundedRectangle(cornerRadius: 8).fill(.white))

🎨 Visual Design Principles

Background Design System

  • ALWAYS include geometric blur background for modern aesthetic
  • Use 4+ overlapping shapes (circles, rounded rectangles) with different gradients
  • Apply .blur(radius: 12-25) for depth
  • Use .offset() for positioning instead of GeometryReader when possible
  • Opacity range: 0.3-0.6 for shapes, 0.9+ for content backgrounds

Color and Contrast

  • Use semantic colors: .primary, .secondary, .blue, etc.
  • Content backgrounds: .white.opacity(0.95) for proper contrast over gradients
  • Status colors: .green (success), .red (error), .orange (warning), .blue (info)
  • Border opacity: 0.2-0.3 for subtle borders

Typography Hierarchy

// Headers
.font(.system(size: 28, weight: .bold))        // Page titles
.font(.system(size: 20, weight: .semibold))    // Section headers  
.font(.system(size: 16, weight: .semibold))    // Form labels

// Body text
.font(.system(size: 16))                       // Primary content
.font(.system(size: 14))                       // Secondary content
.font(.system(size: 12))                       // Captions/metadata

πŸ“± Mobile-First Design

Layout Patterns

  • ALWAYS design for iPhone portrait mode first
  • Use vertical layouts instead of horizontal tables
  • Card-based design for list items instead of wide tables
  • Full-width form fields on mobile
  • Minimum 44pt touch target sizes

Spacing System

// Standard spacing scale
.padding(.horizontal, 20)    // Page margins
VStack(spacing: 24)         // Major section spacing
VStack(spacing: 12)         // Related content spacing
VStack(spacing: 8)          // Tight content spacing
VStack(spacing: 2)          // List item separation

Safe Area Management

  • Add 60pt top spacer for safe area clearance
  • Implement blur overlay for content scrolling into safe area:
VStack {
    Rectangle()
        .fill(.linearGradient(
            colors: [.white.opacity(0.9), .white.opacity(0.7), .clear],
            startPoint: .top,
            endPoint: .bottom
        ))
        .frame(height: 80)
        .blur(radius: 2)
        .allowsHitTesting(false)
    Spacer()
}

πŸ—‚οΈ Component Architecture

Form Field Standards

// Standard form field pattern
VStack(alignment: .leading, spacing: 8) {
    Text("Field Label")
        .font(.system(size: 16, weight: .semibold))
        .foregroundStyle(.primary)
    
    TextField("Placeholder text", text: $binding)
        .padding(.horizontal, 16)
        .padding(.vertical, 16)
        .background(.white.opacity(0.95))
        .clipShape(RoundedRectangle(cornerRadius: 12))
        .overlay(RoundedRectangle(cornerRadius: 12).stroke(.gray.opacity(0.2), lineWidth: 1))
        .shadow(color: .black.opacity(0.05), radius: 4, x: 0, y: 1)
        .keyboardType(.appropriate)
        .submitLabel(.next)
}

Button Styles

// Primary button
Button("Action") { }
    .font(.system(size: 16, weight: .medium))
    .foregroundStyle(.white)
    .frame(maxWidth: .infinity)
    .padding(.vertical, 16)
    .background(.blue)
    .clipShape(.rect(cornerRadius: 12))

// Secondary button  
Button("Cancel") { }
    .font(.system(size: 16, weight: .medium))
    .foregroundStyle(.primary)
    .frame(maxWidth: .infinity)
    .padding(.vertical, 16)
    .background(.white)
    .clipShape(.rect(cornerRadius: 12))
    .overlay(RoundedRectangle(cornerRadius: 12).stroke(.gray.opacity(0.3), lineWidth: 1))

Card Components

// Modern card with shadow
VStack {
    // Card content
}
.padding(16)
.background(.white.opacity(0.95))
.clipShape(.rect(cornerRadius: 12))
.shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 2)

πŸ“‹ Form Design Patterns

Mobile-Optimized Forms

  • ALWAYS use vertical field layout on mobile
  • Use appropriate keyboard types (.emailAddress, .decimalPad, etc.)
  • Include proper text content types for autofill
  • Apply input validation styling with colors
  • Use Menu components for dropdowns with proper styling

Input Field Enhancements

// Email field optimization
TextField("", text: $email)
    .textContentType(.emailAddress)
    .keyboardType(.emailAddress)
    .autocorrectionDisabled()
    .textInputAutocapitalization(.never)
    .submitLabel(.next)

// Password field optimization  
SecureField("", text: $password)
    .textContentType(.password)
    .submitLabel(.go)

🎯 Data Presentation

List/Table Design

  • Use card-based layouts instead of traditional tables on mobile
  • Implement unified containers with minimal spacing between items
  • Use proper status indicators with colors and SF Symbols
  • Include edit/action buttons with appropriate sizing

Status Indicators

// Status badge pattern
HStack(spacing: 4) {
    Image(systemName: "checkmark.circle.fill")
        .font(.system(size: 12))
        .foregroundStyle(.green)
    Text("Completed")
        .font(.system(size: 12, weight: .medium))
        .foregroundStyle(.green)
}
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(.green.opacity(0.1))
.clipShape(.rect(cornerRadius: 12))

⚑ Performance Guidelines

State Management

  • Use .constant("") for non-interactive examples
  • Don't create bindings unnecessarily in static examples
  • Avoid GeometryReader when simple layouts suffice
  • Use appropriate view modifiers for efficiency

Layout Optimization

  • Use LazyVGrid for grid layouts with proper column configuration
  • Implement ScrollView for content that may overflow
  • Use proper frame constraints (.maxWidth: .infinity)
  • Apply clipping and masking efficiently

πŸ› οΈ Development Patterns

Pluggable Components

  • Design main content areas to be modular and reusable
  • Use consistent VStack(spacing: 0) wrapper pattern
  • Include proper Spacer() frames for layout control
  • Make components self-contained with minimal external dependencies

Error Prevention

  • NEVER assume API existence - verify all SwiftUI modifiers
  • Test on typical iPhone portrait dimensions
  • Ensure proper contrast ratios for accessibility
  • Validate touch target sizes for usability

Code Organization

// Standard view structure
ZStack {
    // Background layer
    GeometricBlurBackground()
    
    ScrollView {
        VStack(spacing: 0) {
            // Safe area spacer
            Spacer().frame(height: 60)
            
            // Content sections
            ContentSection()
            
            // Bottom spacer  
            Spacer().frame(height: 40)
        }
    }
    
    // Overlay elements
    SafeAreaBlurOverlay()
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea(.all, edges: .top)

πŸ“ Responsive Design

Breakpoint Considerations

  • Design primarily for iPhone portrait (375-430pt width)
  • Use flexible layouts that adapt to different screen sizes
  • Ensure content remains readable and accessible
  • Test with both small (iPhone SE) and large (iPhone Pro Max) screens

Content Adaptation

  • Use .frame(maxWidth: .infinity) for responsive width
  • Implement proper text wrapping and line limits
  • Scale font sizes appropriately for different screen sizes
  • Maintain consistent padding and margins across devices

βœ… Quick Checklist

Before completing any SwiftUI view:

  • Uses modern SwiftUI APIs (no deprecated methods)
  • Includes geometric blur background
  • Implements safe area blur overlay
  • Uses semantic colors and proper contrast
  • Optimized for mobile portrait layout
  • Includes appropriate spacing and padding
  • Uses proper typography hierarchy
  • Implements consistent button and card styles
  • Includes proper form field enhancements
  • Tests on typical iPhone screen dimensions
  • Follows pluggable component architecture
  • No invented or non-existent APIs used
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment