Skip to content
All essays
iOSMarch 27, 202515 min

SwiftUI Complete Guide: Modern iOS UI Development

Declarative UI development with SwiftUI. Views, modifiers, state management, and layout system.

Ü
Ümit Uz
Mobile & Full Stack Developer

SwiftUI is Apple's modern declarative UI framework introduced in 2019. It allows faster development with less code compared to UIKit.

Basic SwiftUI Structure

swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, SwiftUI!")
    }
}

Basic Views

swift
VStack(spacing: 20) {
    // Text
    Text("Title")
        .font(.largeTitle)
        .fontWeight(.bold)

    // Image
    Image(systemName: "heart.fill")
        .foregroundColor(.red)
        .font(.largeTitle)

    // Button
    Button(action: {
        print("Clicked!")
    }) {
        Text("Click Me")
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
    }

    // TextField
    TextField("Enter name", text: $name)
        .textFieldStyle(RoundedBorderTextFieldStyle())
        .padding()
}

Layout System

VStack - Vertical Layout

swift
VStack(alignment: .leading, spacing: 10) {
    Text("Row 1")
    Text("Row 2")
    Text("Row 3")
}
.padding()

HStack - Horizontal Layout

swift
HStack(spacing: 20) {
    Text("Left")
    Spacer()
    Text("Center")
    Spacer()
    Text("Right")
}
.padding()

ZStack - Layered Layout

swift
ZStack {
    Circle()
        .fill(Color.blue)
        .frame(width: 150, height: 150)

    Text("Hello")
        .foregroundColor(.white)
        .font(.title)
}

State Management

@State

swift
struct CounterView: View {
    @State private var count = 0

    var body: some View {
        VStack {
            Text("Count: \(count)")
                .font(.largeTitle)

            Button("Increment") {
                count += 1
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(10)
        }
    }
}

@Binding

swift
struct ChildView: View {
    @Binding var isOn: Bool

    var body: some View {
        Toggle("Notifications", isOn: $isOn)
    }
}

struct ParentView: View {
    @State private var notificationsEnabled = false

    var body: some View {
        ChildView(isOn: $notificationsEnabled)
    }
}

@StateObject and @ObservedObject

swift
class ViewModel: ObservableObject {
    @Published var items: [String] = []

    func addItem() {
        items.append("New item")
    }
}

struct ItemsView: View {
    @StateObject private var viewModel = ViewModel()

    var body: some View {
        List {
            ForEach(viewModel.items, id: \.self) { item in
                Text(item)
            }
        }
        .overlay(
            Button("Add") {
                viewModel.addItem()
            }
            .padding(),
            alignment: .bottom
        )
    }
}

Lists and Navigation

swift
struct Item: Identifiable {
    let id = UUID()
    let name: String
}

struct ListView: View {
    let items = [
        Item(name: "Apple"),
        Item(name: "Pear"),
        Item(name: "Banana")
    ]

    var body: some View {
        NavigationView {
            List(items) { item in
                NavigationLink(destination: DetailView(item: item)) {
                    Text(item.name)
                }
            }
            .navigationTitle("Fruits")
        }
    }
}

struct DetailView: View {
    let item: Item

    var body: some View {
        VStack {
            Text(item.name)
                .font(.largeTitle)
            Text("Detail page")
                .foregroundColor(.gray)
        }
        .navigationTitle(item.name)
    }
}

Modifiers

swift
Text("SwiftUI")
    .font(.title)
    .fontWeight(.bold)
    .foregroundColor(.blue)
    .padding()
    .background(Color.yellow)
    .cornerRadius(10)
    .shadow(radius: 5)
    .rotationEffect(.degrees(45))

Custom Views

swift
struct ProfileCard: View {
    let name: String
    let role: String

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Circle()
                .fill(Color.blue)
                .frame(width: 60, height: 60)

            Text(name)
                .font(.headline)

            Text(role)
                .font(.subheadline)
                .foregroundColor(.secondary)
        }
        .padding()
        .frame(maxWidth: .infinity)
        .background(Color.gray.opacity(0.1))
        .cornerRadius(12)
    }
}

// Usage
ProfileCard(name: "John Doe", role: "iOS Developer")

Animations

swift
struct AnimationView: View {
    @State private var isAnimating = false

    var body: some View {
        Circle()
            .fill(Color.blue)
            .frame(width: 100, height: 100)
            .scaleEffect(isAnimating ? 1.5 : 1.0)
            .animation(
                .easeInOut(duration: 0.5)
                .repeatForever(),
                value: isAnimating
            )
            .onAppear {
                isAnimating = true
            }
    }
}

Gestures

swift
struct GestureView: View {
    @State private var offset = CGSize.zero
    @State private var isDragging = false

    var body: some View {
        Circle()
            .fill(isDragging ? Color.red : Color.blue)
            .frame(width: 100, height: 100)
            .offset(offset)
            .gesture(
                DragGesture()
                    .onChanged { value in
                        isDragging = true
                        offset = value.translation
                    }
                    .onEnded { _ in
                        isDragging = false
                        offset = .zero
                    }
            )
    }
}

SwiftUI Best Practices

  1. 1Keep views small: Each view should have a single responsibility
  2. 2Use Previews: Speed up development with #Preview macro
  3. 3Custom modifiers: Eliminate repetitive code with custom modifiers
  4. 4State management: Choose the right state management pattern
  5. 5Performance: Use LazyVStack/LazyHStack for large lists

SwiftUI is the future of iOS development!

Related essays

Next essay
Swift Combine Framework: Asynchronous Programming