DEV Community

Daniil Kornilov
Daniil Kornilov

Posted on Edited on

Seven SwiftUI features illustrated with small examples

Disclosure: This article was created or edited with AI assistance. It is educational guidance, not a report of measured results. No measured productivity, hiring, sales or income outcome is claimed. Examples are illustrative unless a source is explicitly given.

The code blocks are educational examples, not a verified production package. Check dependencies, platform compatibility and behavior in your own project.

Example patterns to explore

These snippets illustrate selected SwiftUI and related framework features. They are separate sketches, not a complete app. Check API availability for your Xcode version and deployment target. App-specific types such as User, Item, TaskRow and previewContainer must be supplied by the project.

1. @observable Macro (iOS 17+)

The Observation model offers another way to describe observable state. Existing ObservableObject-based code may still be appropriate for a project.

// Before (old way)
class UserViewModel: ObservableObject {
    @Published var name = ""
    @Published var isLoading = false
}

// After (new way)
@Observable
class UserViewModel {
    var name = ""
    var isLoading = false
}
Enter fullscreen mode Exit fullscreen mode

What to compare: The declarations and dependencies needed by your own views. Measure performance in your actual app rather than assuming a speedup.

2. NavigationStack with Type-Safe Routing

@Observable
class Router {
    var path = NavigationPath()

    func navigate(to destination: AppDestination) {
        path.append(destination)
    }

    func popToRoot() {
        path = NavigationPath()
    }
}

enum AppDestination: Hashable {
    case profile(User)
    case settings
    case detail(Item)
}

struct ContentView: View {
    @State private var router = Router()

    var body: some View {
        NavigationStack(path: $router.path) {
            HomeView()
                .navigationDestination(for: AppDestination.self) { dest in
                    switch dest {
                    case .profile(let user): ProfileView(user: user)
                    case .settings: SettingsView()
                    case .detail(let item): DetailView(item: item)
                    }
                }
        }
        .environment(router)
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Swift Data Integration

Here is an illustrative SwiftData model and query:

@Model
class Task {
    var title: String
    var isCompleted: Bool
    var createdAt: Date

    init(title: String) {
        self.title = title
        self.isCompleted = false
        self.createdAt = .now
    }
}

struct TaskListView: View {
    @Query(sort: \Task.createdAt, order: .reverse) var tasks: [Task]
    @Environment(\.modelContext) var context

    var body: some View {
        List(tasks) { task in
            TaskRow(task: task)
                .swipeActions {
                    Button("Delete", role: .destructive) {
                        context.delete(task)
                    }
                }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Custom Containers & Composable Layouts

struct CardContainer<Content: View>: View {
    @ViewBuilder var content: Content

    var body: some View {
        VStack(spacing: 12) {
            content
        }
        .padding()
        .background(.regularMaterial)
        .clipShape(RoundedRectangle(cornerRadius: 16))
        .shadow(radius: 4)
    }
}

// Usage
CardContainer {
    Text("Title").font(.headline)
    Text("Subtitle").foregroundStyle(.secondary)
    Button("Action") { }
}
Enter fullscreen mode Exit fullscreen mode

5. Improved Animations

struct AnimatedCard: View {
    @State private var isExpanded = false

    var body: some View {
        VStack {
            Text("Tap to expand")
            if isExpanded {
                Text("Extra content here")
                    .transition(.move(edge: .bottom).combined(with: .opacity))
            }
        }
        .animation(.spring(duration: 0.4, bounce: 0.3), value: isExpanded)
        .onTapGesture { isExpanded.toggle() }
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Native Charts

import Charts

struct RevenueChart: View {
    let data: [DailyRevenue]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Day", item.date, unit: .day),
                y: .value("Revenue", item.amount)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxis { AxisMarks(values: .stride(by: .day)) }
    }
}
Enter fullscreen mode Exit fullscreen mode

7. Preview Macros

#Preview("Light Mode") {
    ContentView()
        .environment(\.colorScheme, .light)
}

#Preview("Dark Mode") {
    ContentView()
        .environment(\.colorScheme, .dark)
}

#Preview("With Data") {
    ContentView()
        .modelContainer(previewContainer)
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)