System-Style SwiftUI Views Cheat Sheet

From Qiki
Revision as of 04:25, 1 January 2026 by Ryan (talk | contribs) (Created page with " <span id="system-style-swiftui-views-cheat-sheet"></span> = System-Style SwiftUI Views Cheat Sheet = This document focuses on '''ready-made, opinionated system views''' you can drop in to get platform‑native UI with minimal code — similar in spirit to <code>ContentUnavailableView</code>. ----- <span id="contentunavailableview-empty-error-states"></span> == 1. <code>ContentUnavailableView</code> – Empty & Error States == '''Availability:''' iOS 17+, macOS...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

System-Style SwiftUI Views Cheat Sheet

This document focuses on ready-made, opinionated system views you can drop in to get platform‑native UI with minimal code — similar in spirit to ContentUnavailableView.



1. ContentUnavailableView – Empty & Error States

Availability: iOS 17+, macOS 14+, tvOS 17+, watchOS 10+ (SwiftyLion)

Use this when your feature has no content to show (empty list, no search results, offline, etc.).

struct EmptyStateExample: View {
    let items: [String] = []

    var body: some View {
        List(items, id: \.self) { item in
            Text(item)
        }
        .overlay {
            if items.isEmpty {
                ContentUnavailableView(
                    "No Favorites Yet",
                    systemImage: "star",
                    description: Text("Tap the star on an item to add it here.")
                )
            }
        }
    }
}

There’s also a built-in search variant:

.overlay {
    if searchResults.isEmpty {
        ContentUnavailableView.search(text: searchText)
    }
}

2. ProgressView – Loading & Progress Indicators

Availability: iOS 14+ (all Apple platforms) (Apple Developer)

A system progress indicator with automatic styling (circular or linear) and support for determinate / indeterminate states.

Indeterminate (spinner)

ProgressView("Loading…")
    .progressViewStyle(.circular)

Determinate (progress bar)

struct DownloadView: View {
    @State private var progress: Double = 0.4

    var body: some View {
        VStack {
            ProgressView(value: progress) {
                Text("Downloading")
            } currentValueLabel: {
                Text("\(Int(progress * 100))%")
            }
        }
        .padding()
    }
}

Built-in styles include .automatic, .linear, and .circular. (Apple Developer)



3. Gauge – Meter-Style Value Display

Availability: iOS 16+, macOS 13+, watchOS 9+ (Use Your Loaf)

A meter-style control for things like battery, speed, or progress — visually richer than ProgressView.

struct BatteryGauge: View {
    @State private var level = 0.65

    var body: some View {
        Gauge(value: level, in: 0...1) {
            Text("Battery")
        } currentValueLabel: {
            Text("\(Int(level * 100))%")
        }
        .gaugeStyle(.accessoryCircularCapacity)
        .tint(.green)
        .padding()
    }
}

Gauge supports multiple styles (linear, circular, accessory variants) and automatically adapts to platform. (Apple Developer)



4. Label – Icon + Text in One View

Availability: iOS 14+

Label is a small thing but extremely useful: it wraps SF Symbol + Text with system‑standard spacing and accessibility.

Label("Settings", systemImage: "gear")
    .labelStyle(.titleAndIcon)

Label("Downloads", systemImage: "arrow.down.circle")
    .labelStyle(.iconOnly)       // just the icon

Many other system views (e.g. ShareLink, menus, toolbars) use Label under the hood, so learning it pays off.



Availability: iOS 16+, iPadOS 16+, macOS 13+, watchOS 9+ (Apple Developer)

A SwiftUI-native share sheet. Great when you want to share URLs, text, images, or Transferable types with almost no boilerplate.

Share a URL

struct ShareArticleButton: View {
    let url = URL(string: "https://developer.apple.com")!

    var body: some View {
        ShareLink(item: url) {
            Label("Share Article", systemImage: "square.and.arrow.up")
        }
    }
}

Share an image with a custom preview

struct ShareImageButton: View {
    let image = Image("cute-dog")

    var body: some View {
        ShareLink(
            "Share Dog",
            item: image,
            preview: SharePreview("Cute dog", image: image)
        )
    }
}

Because it uses the system share sheet, you automatically get any share destinations the user has installed.



6. PhotosPicker – Native Photo Library Picker

Availability: iOS 16+, iPadOS 16+, macOS 13+, watchOS 9+ (Apple Developer)

SwiftUI’s built‑in view for selecting photos and videos from the system photo library.

import PhotosUI

struct PhotoSelectorView: View {
    @State private var selection: [PhotosPickerItem] = []
    @State private var selectedImage: Image?

    var body: some View {
        VStack {
            PhotosPicker(
                selection: $selection,
                maxSelectionCount: 1,
                matching: .images
            ) {
                Label("Select Photo", systemImage: "photo")
            }

            if let selectedImage {
                selectedImage
                    .resizable()
                    .scaledToFit()
                    .frame(height: 200)
            }
        }
        .task(id: selection) {
            guard let item = selection.first else { return }
            if let data = try? await item.loadTransferable(type: Data.self),
               let uiImage = UIImage(data: data) {
                selectedImage = Image(uiImage: uiImage)
            }
        }
    }
}

This handles the whole photo-picking experience with system UI, and uses the Transferable API under the hood.



7. Map (MapKit for SwiftUI) – System Maps

Availability: modern iOS/macOS/watchOS versions via MapKit for SwiftUI (Apple Developer)

A SwiftUI-native map view from MapKit that lets you show Apple Maps with annotations, overlays, and camera control.

import MapKit

struct SimpleMapView: View {
    @State private var position: MapCameraPosition = .region(
        .init(
            center: .init(latitude: 37.334_900, longitude: -122.009_020),
            span: .init(latitudeDelta: 0.05, longitudeDelta: 0.05)
        )
    )

    var body: some View {
        Map(position: $position) {
            Marker("Apple Park", coordinate: .init(
                latitude: 37.334_900,
                longitude: -122.009_020
            ))
        }
        .mapStyle(.standard(elevation: .realistic))
    }
}

Compared to rolling your own map wrapper, the new MapKit+SwiftUI APIs give you a rich, declarative API with platform‑native styling.



8. Form, List, Section – System Lists & Forms

These are older but still very much in the same spirit: drop-in containers that immediately look like system UI.

Form – Settings-style screens

struct SettingsForm: View {
    @State private var notifications = true
    @State private var username = ""

    var body: some View {
        Form {
            Section("Account") {
                TextField("Username", text: $username)
            }

            Section("Notifications") {
                Toggle("Enable notifications", isOn: $notifications)
            }
        }
    }
}

Form automatically gives you grouped sections, appropriate padding, and platform‑native behavior (e.g. differently on macOS vs iOS).

List + Section – Table/List screens

struct ContactsListView: View {
    let favorites: [String]
    let others: [String]

    var body: some View {
        List {
            Section("Favorites") {
                ForEach(favorites, id: \.self, content: Text.init)
            }

            Section("All Contacts") {
                ForEach(others, id: \.self, content: Text.init)
            }
        }
    }
}

The List/Form/Section triad is your go‑to for “default iOS look” with very little effort.



9. Menu – Pull-Down / Context Menus

Availability: iOS 14+

A built‑in control for showing a system‑styled menu that can live in toolbars, nav bars, or inline.

struct SortMenu: View {
    @State private var sortOption = "Date"

    var body: some View {
        Menu {
            Button("Date")   { sortOption = "Date" }
            Button("Name")   { sortOption = "Name" }
            Button("Rating") { sortOption = "Rating" }
        } label: {
            Label("Sort: \(sortOption)", systemImage: "arrow.up.arrow.down")
        }
    }
}

On iOS, this becomes a pull‑down; on macOS, it renders more like a standard menu button.



10. Picker, DatePicker, ColorPicker – System Input Controls

These are all Views that render as the native control for the current platform.

Picker

Picker("Sort by", selection: $sortOption) {
    Text("Date").tag("date")
    Text("Name").tag("name")
}
.pickerStyle(.segmented)

DatePicker

DatePicker("Due Date", selection: $dueDate, displayedComponents: .date)
    .datePickerStyle(.compact)

ColorPicker

ColorPicker("Tint Color", selection: $tintColor, supportsOpacity: false)

All of these automatically adapt to device type, input method, and accessibility settings.



Where to Go From Here

If you like ContentUnavailableView, you’ll probably also get a lot of value from:

  • ProgressView & Gauge for loading/metrics.
  • ShareLink and PhotosPicker for “system-y” flows with almost no UI code.
  • Map for rich map experiences with native controls.
  • Form / List / Section / Menu / various pickers for standard controls and layouts.