Snippets
Small SwiftUI patterns I keep around for platform-aware interfaces, navigation, sharing, and presentation.
Put platform-specific controls in the safe area
struct EditorShell: View {
#if os(visionOS)
var body: some View {
TextEditor(text: $draft)
.ornament(
visibility: .visible,
attachmentAnchor: .scene(.bottom)
) {
Button("Close") { dismiss() }
}
}
#else
var body: some View {
TextEditor(text: $draft)
.safeAreaInset(edge: .bottom) {
Button("Close") { dismiss() }
.frame(maxWidth: .infinity)
}
}
#endif
}Run a side effect when a tab is selected
enum Tab: Hashable {
case library
case settings
}
struct RootView: View {
@State private var tab = Tab.library
var body: some View {
TabView(selection: Binding(
get: { tab },
set: { nextTab in
if nextTab == .settings { presentComposer() }
tab = nextTab
}
)) {
LibraryView().tag(Tab.library)
SettingsView().tag(Tab.settings)
}
}
}Make a remote image shareable
struct RemoteImage: Transferable {
let data: Data
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(exportedContentType: .png) { image in
image.data
}
}
}
func loadImage(from url: URL) async throws -> RemoteImage {
let (data, _) = try await URLSession.shared.data(from: url)
return RemoteImage(data: data)
}Keep an AppDelegate in a SwiftUI app
@main
struct ReaderApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self)
private var appDelegate
var body: some Scene {
WindowGroup { LibraryView() }
}
}
final class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
configureAudio()
return true
}
}Drive NavigationStack with a typed route
enum Route: Hashable {
case document(UUID)
case settings
}
struct AppShell: View {
@State private var path: [Route] = []
var body: some View {
NavigationStack(path: $path) {
LibraryView()
.navigationDestination(for: Route.self) { route in
switch route {
case .document(let id): ReaderView(documentID: id)
case .settings: SettingsView()
}
}
}
}
}Present a focused settings sheet
struct LibraryToolbar: View {
@State private var showingSettings = false
var body: some View {
Button("Settings") { showingSettings = true }
.sheet(isPresented: $showingSettings) {
SettingsView()
.presentationDetents([.medium])
.presentationBackground(.thinMaterial)
.presentationCornerRadius(24)
}
}
}Use let for values that should not drift
struct ReaderSettings {
let documentID: UUID
var speed: Double
}
var settings = ReaderSettings(documentID: documentID, speed: 1.0)
settings.speed = 1.25
// settings.documentID = anotherID // Compile-time errorChoose if let or guard let for optional values
func titleUsingIf(_ document: Document?) -> String {
if let document { return document.title }
return "Untitled"
}
func titleUsingGuard(_ document: Document?) -> String {
guard let document else { return "Untitled" }
return document.title
}Remove duplicates without losing order
func uniquePreservingOrder<T: Hashable>(_ values: [T]) -> [T] {
var seen = Set<T>()
return values.filter { seen.insert($0).inserted }
}
let chapters = uniquePreservingOrder(["intro", "setup", "intro"])
// ["intro", "setup"]Treat string-to-number conversion as fallible
func parseCount(_ text: String) -> Int? {
Int(text.trimmingCharacters(in: .whitespacesAndNewlines))
}
if let count = parseCount("42") {
print("Loaded \(count) items")
}Sort models by the property people read
struct Book {
let title: String
}
let sortedBooks = books.sorted {
$0.title.localizedCaseInsensitiveCompare($1.title)
== .orderedAscending
}