SwiftUI в мобільній розробці: що це, ключові поняття та як працює

Автор: IT Sectr Опубліковано: 2026-07-02 Час читання: 10 хв
SwiftUI — декларативний фреймворк Apple для побудови інтерфейсів на всіх платформах. За даними Apple SwiftUI Docs (2025), SwiftUI використовується в 70% нових додатків в App Store. Розуміння ключових понять SwiftUI — View Protocol, @ViewBuilder, NavigationStack — основа сучасної iOS-розробки.

Головне

  • View Protocol — var body: some View. Кожна View — структура, що відповідає протоколу View. body — опис UI.
  • @ViewBuilder — Result Builder для множинних View у контейнерах. if/else, switch, ForEach всередині body.
  • NavigationStack (iOS 16+) — data-driven навігація. path-based, deep linking. Заміна NavigationView.
  • @StateObject — володіння об'єктом. @ObservedObject — спостереження. @EnvironmentObject — оточення.
  • @FocusState — керування фокусом. .task{}, .onAppear{} — життєвий цикл. PreviewProvider — попередній перегляд.

Основи (View Protocol, body, some View, @ViewBuilder)

View Protocol — центральний протокол SwiftUI. Вимагає єдину властивість: var body: some View. body — це обчислювана властивість, що повертає опис UI. SwiftUI викликає body при кожній зміні стану та рендерить результат на GPU.

@ViewBuilder

@ViewBuilder — Result Builder для View. Дозволяє писати кілька View всередині замикання без return і без TupleView. Підтримує if/else, switch, ForEach. Всі контейнери (VStack, HStack, ZStack, Group) використовують @ViewBuilder. Альтернатива — Group { … } для групування без компонування. some View — Opaque Type. Компілятор знає конкретний тип View (Text, Button, VStack тощо), але зовні повертається як some View. Це дозволяє змінювати тип body без зміни сигнатури. ViewModifier — модифікатор View: .font(), .padding(), .background(). Користувацький модифікатор через ViewModifier protocol та .modifier().

swift
// Приклад View з @ViewBuilder та NavigationStack
struct ContentView: View {
    @State private var items = ["Item 1", "Item 2"]

    var body: some View {
        NavigationStack {
            List(items, id: .self) { item in
                NavigationLink(item) {
                    DetailView(item: item)
                }
            }
            .navigationTitle("Items")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Add") {
                        items.append("New Item")
                    }
                }
            }
        }
    }
}

// DetailView з @StateObject
struct DetailView: View {
    let item: String
    @StateObject private var viewModel = DetailViewModel()

    var body: some View {
        Text(item)
            .task {
                await viewModel.loadDetails(for: item)
            }
    }
}

Модифікатори та контейнери (ViewModifier, NavigationStack, List, Form)

NavigationStack (iOS 16+) — data-driven навігація. Приймає шлях (масив hashable значень) і відображає призначення через navigationDestination. Замінює NavigationLink з видами призначення. NavigationLink — кнопка для навігації стеком. List — вертикальний список з можливістю секцій, свайпів, видалення та перетягування. Form — спеціалізований List для налаштувань: секції, пікери, перемикачі, текстові поля. Section — групування в List/Form із заголовком та футером. ViewModifier — користувацькі модифікатори для повторного використання стилів. .modifier(CustomModifier()) — застосування.

List і Form в деталях

List в SwiftUI — аналог UITableView. Підтримує .onDelete, .onMove, .refreshable. SwipeActions — .swipeActions { Button("Видалити", role: .destructive) { } }. Form — оптимізований для налаштувань: DatePicker, Toggle, Stepper, Picker. Section з header/footer — для групування. OutlineGroup — ієрархічні списки (аналог UITableView з секціями). DisclosureGroup — згортана секція з контентом. IT Sectr рекомендує List для даних і Form для налаштувань.

PreviewProvider — протокол для попереднього перегляду в Xcode Canvas. Canvas — інтерактивний попередній перегляд SwiftUI (вимагає @main та Swift 5.9+). @ScaledMetric — адаптивний розмір, що масштабується з Dynamic Type.

Керування станом (@StateObject, @ObservedObject, @EnvironmentObject, @FocusState)

Property Wrappers — основа керування станом у SwiftUI. @State — локальний стан (value type). @Binding — зв'язок зі станом батька. @StateObject — створення ObservableObject. SwiftUI керує життєвим циклом об'єкта. @ObservedObject — спостереження за зовнішнім ObservableObject. @EnvironmentObject — об'єкт з оточення (впровадження залежностей через .environmentObject()). @Environment — системні значення (.colorScheme, .locale). @AppStorage — UserDefaults. @FetchRequest — Core Data запит. @FocusState — фокус введення.

Обгортка Призначення Володіння
@StateЛокальний стан (value type)View володіє
@BindingЗв'язок із батьківським станомБатько володіє
@StateObjectСтворення ObservableObjectView володіє
@ObservedObjectСпостереження зовнішнього об'єктаЗовнішній власник
@EnvironmentObjectОб'єкт з оточенняПредок володіє
@EnvironmentСистемне значенняСистема
@AppStorageUserDefaultsUserDefaults
@FocusStateФокус введенняView володіє

@StateObject vs @ObservedObject: @StateObject створює об'єкт, @ObservedObject спостерігає. Використовуйте @StateObject для першого створення моделі в ієрархії, @ObservedObject — для передачі дочірнім view. @FocusState — керування фокусом: .focused($field, equals: .email). Підтримує enum для кількох полів.

Environment Values та DI

@Environment — системні значення: colorScheme, locale, sizeCategory, layoutDirection, managedObjectContext. Користувацькі Environment Values — користувацьке значення через EnvironmentKey. Використовується для впровадження залежностей: передача сервісів без явних параметрів. Модифікатор .environment() — встановлення значення в ієрархії. @EnvironmentObject — ObservableObject з .environmentObject(). Відрізняється від @Environment тим, що передає reference type. IT Sectr рекомендує @Environment для системних значень і @EnvironmentObject для сервісів.

Життєвий цикл (.task, .onAppear, .onDisappear)

.task{} — async операція при появі view. Автоскасування при зникненні. Заміна .onAppear для async/await. .onAppear{} — синхронна операція при появі. .onDisappear{} — операція при зникненні. .onChange(of:) — реакція на зміну значення. .onReceive(Publisher) — реакція на Combine publisher. Життєвий цикл View у SwiftUI: init → onAppear → body (рендеринг) → onDisappear. При зміні стану: body → diff → ререндеринг. IT Sectr рекомендує .task для асинхронного завантаження та .onAppear для аналітики.

Анімація в SwiftUI

.animation() — модифікатор анімації. .transition() — анімація появи/зникнення. withAnimation — явна анімація змін стану. matchedGeometryEffect — анімація між різними view (hero animation). PhaseAnimator (iOS 17+) — багатофазна анімація на основі enum. KeyframeAnimator (iOS 17+) — покадрова анімація з keyframes. Анімації SwiftUI виконуються на GPU через Core Animation. IT Sectr рекомендує .spring() для природних анімацій та .interpolatingSpring для фізичних ефектів.

Data Flow (Bindings, @Published, ObservableObject)

ObservableObject — протокол для об'єктів із @Published властивостями. SwiftUI підписується на objectWillChange publisher. @Published — публікує зміни властивості. @StateObject — створює ObservableObject, керує життєвим циклом. @ObservedObject — спостерігає зовнішній. Combine — фреймворк для реактивного програмування. @EnvironmentObject — DI через оточення. .environmentObject() встановлює, @EnvironmentObject читає. MVVM — стандартна архітектура: View (SwiftUI) — ViewModel (ObservableObject) — Model. IT Sectr рекомендує MVVM + @StateObject для основних ViewModel.

swift
class UserViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false

    func loadUsers() async {
        isLoading = true
        defer { isLoading = false }
        do {
            users = try await api.fetchUsers()
        } catch {
            print("Помилка: \(error)")
        }
    }
}

struct UsersView: View {
    @StateObject private var viewModel = UserViewModel()

    var body: some View {
        List(viewModel.users, id: \.id) { user in
            Text(user.name)
        }
        .task { await viewModel.loadUsers() }
        .overlay {
            if viewModel.isLoading { ProgressView() }
        }
    }
}

Accessibility та локалізація

Accessibility в SwiftUI: .accessibilityLabel(), .accessibilityHint(), .accessibilityValue(), .accessibilityAddTraits(). VoiceOver читає accessibility-мітки. Dynamic Type — @ScaledMetric, @DynamicProperty. Локалізація: String(localized:) (SwiftUI + String Catalog). LocalizedStringKey — автоматичний переклад. Правила множини — через String Catalog (one, few, many, other). Right-to-Left (арабська, іврит) — підтримується автоматично. .environment(.layoutDirection, .rightToLeft). IT Sectr рекомендує accessibility-мітки для всіх інтерактивних елементів.

swift
struct AccessibleButton: View {
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Label("Settings", systemImage: "gear")
        }
        .accessibilityLabel("Open Settings")
        .accessibilityHint("Double tap to navigate to settings screen")
        .accessibilityAddTraits(.isButton)
    }
}

// Підтримка Dynamic Type
struct ScalableText: View {
    @ScaledMetric private var fontSize: CGFloat = 17

    var body: some View {
        Text("Hello, World!")
            .font(.system(size: fontSize))
    }
}

Діаграми та візуалізація (Swift Charts)

Swift Charts (iOS 16+) — фреймворк для побудови графіків. Chart { } — базовий контейнер. BarMark, LineMark, PointMark, AreaMark, RuleMark — маркери. ForEach для даних. ChartAxis — кастомізація осей. .chartXAxis, .chartYAxis. ChartLegend — легенда. Інтерполяція — catmullRom, linear, step. Анімація — .animation() для Chart. IT Sectr рекомендує Swift Charts для вбудованих графіків і Charts (DGCharts) для складних.

swift
import Charts

struct MonthlySales: Identifiable {
    let id = UUID()
    let month: String
    let sales: Double
}

struct SalesChart: View {
    let data: [MonthlySales]

    var body: some View {
        Chart(data) { item in
            BarMark(
                x: .value("Month", item.month),
                y: .value("Sales", item.sales)
            )
            .foregroundStyle(.blue.gradient)
        }
        .chartXAxisLabel("Month")
        .chartYAxisLabel("Sales")
        .frame(height: 200)
        .padding()
    }
}

Swift Package Manager (SPM) — менеджер залежностей Apple. Інтегрований у Xcode. Підтримує: бінарні пакети, ресурси, тести, swift-6 сувору конкурентність. Публікація пакетів через GitHub із тегом semver. SPM — стандарт де-факто для Swift-залежностей, який витісняє CocoaPods та Carthage. IT Sectr рекомендує SPM для всіх нових проєктів.

Swift Concurrency (async/await, TaskGroup, AsyncSequence) — async/await вбудовані у Swift 5.5+. Task — одиниця асинхронності. TaskGroup — паралельні завдання. AsyncSequence — асинхронна послідовність (AsyncStream, AsyncAlgorithms). Task Local Values — контекстні дані для Task. Swift Concurrency повністю замінює Combine для асинхронних операцій.

Часто задавані питання

Що таке View Protocol в SwiftUI?

View Protocol — базовий протокол. Вимагає var body: some View. body — опис UI, що рендериться на GPU.

Що таке @ViewBuilder і для чого він потрібен?

@ViewBuilder — Result Builder для множинних View. Дозволяє if/else, switch, ForEach всередині контейнерів.

В чому різниця між @StateObject та @ObservedObject?

@StateObject створює об'єкт. @ObservedObject спостерігає існуючий. @StateObject для першого створення в ієрархії.

Що таке NavigationStack в iOS 16+?

NavigationStack — data-driven навігація. path-based, deep linking. Замінює NavigationView.

Як працює @FocusState в SwiftUI?

@FocusState — керування фокусом введення. Модифікатор .focused(). Підтримує enum для кількох полів.

Підсумки

  • View Protocol — var body: some View. Основа SwiftUI. Кожна View — struct.
  • @ViewBuilder — декларативний синтаксис множинних View. if/else, ForEach всередині body.
  • NavigationStack (iOS 16+) — сучасна навігація. data-driven, path-based.
  • @StateObject — володіння моделлю. @ObservedObject — спостереження. @EnvironmentObject — DI.
  • @FocusState — керування фокусом. Зручно для форм та множинних полів введення.
  • .task{} — async операція з автоскасуванням. .onAppear{} — синхронна.
  • PreviewProvider та Canvas — попередній перегляд в Xcode. @ScaledMetric — адаптивні розміри.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект