SwiftUI: первый экран с Text, Button и @State

В этом уроке мы сделаем первый интерактивный экран SwiftUI: текст, кнопку, вертикальный layout и счетчик через @State. Это мини-проект без архитектурной перегрузки. Наша цель — увидеть, как SwiftUI view описывает экран и почему изменение state перерисовывает интерфейс

К концу урока у вас будет экран со счетчиком, который работает в Preview или Simulator

Что получится в конце

Файл ContentView.swift:

import SwiftUI

struct ContentView: View {
    @State private var count = 0

    var body: some View {
        VStack(spacing: 16) {
            Text("SwiftUI counter")
                .font(.title)

            Text("Clicks: \(count)")

            Button("Add") {
                count += 1
            }
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

В Preview появится заголовок, счетчик и кнопка. Нажатие кнопки увеличит число

Что нужно заранее

Нужен Xcode и проект с SwiftUI interface. Если Xcode еще не установлен, сначала откройте Как установить Xcode и создать первый Swift-проект

SwiftUI лучше изучать после базового Swift: let, var, struct, функции, optionals и коллекции. Но первый экран можно собрать уже сейчас, если вы готовы читать код постепенно

View как struct

SwiftUI экран обычно описывается структурой:

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

ContentView соответствует протоколу View. body возвращает описание интерфейса

Это не imperative-код в стиле «создай label, поставь координаты, добавь на экран». SwiftUI описывает, каким должен быть UI для текущего состояния

Text, VStack и modifiers

Text показывает текст:

Text("SwiftUI counter")

VStack складывает элементы вертикально:

VStack(spacing: 16) {
    Text("Title")
    Text("Subtitle")
}

Modifiers настраивают view:

Text("SwiftUI counter")
    .font(.title)

Они читаются цепочкой сверху вниз. Не надо сразу знать все modifiers. Для первого экрана хватит font, padding, foregroundStyle, background

Button и действие

Кнопка:

Button("Add") {
    count += 1
}

Первый аргумент — текст кнопки. Блок в фигурных скобках — действие по нажатию

Если внутри действия ничего не происходит, кнопка видна, но бесполезна. В нашем примере действие меняет count

@State: локальное состояние экрана

Строка:

@State private var count = 0

говорит SwiftUI: это локальное состояние view. Когда count меняется, SwiftUI пересчитывает body, и экран показывает новое значение

private показывает, что состояние принадлежит этому view. Другие views не должны менять его напрямую. Когда понадобится передать состояние в дочерний view, появится @Binding

Не используйте @State для всего подряд. Он хорош для локального состояния небольшого view: счетчик, переключатель, выбранный фильтр, текст поля

Preview: быстрый цикл проверки

#Preview показывает view в Xcode canvas:

#Preview {
    ContentView()
}

Если Preview не обновляется, сначала соберите проект. Если сборка красная, Preview не обязан работать

Preview — ваш быстрый стенд. Меняете текст, spacing, padding, состояние — сразу смотрите результат без полного запуска приложения

Домашка: кнопка сброса

Добавьте вторую кнопку:

Button("Reset") {
    count = 0
}

Проверьте:

  • Add увеличивает счетчик
  • Reset возвращает ноль
  • Preview не падает

Дополнительная задача: если count == 0, показывать текст "No clicks yet", иначе "Clicks: \(count)"

Мини-практика: условный текст

Добавьте:

if count == 0 {
    Text("No clicks yet")
} else {
    Text("Clicks: \(count)")
}

SwiftUI позволяет писать условия внутри body. Это удобно, но не превращайте body в огромную функцию. Когда экран растет, выносите части в отдельные views

Частые ошибки и порядок проверки

Cannot assign to property: self is immutable Скорее всего, вы пытаетесь менять обычное свойство view без @State

Preview не показывает изменения Сначала проверьте сборку проекта. Потом обновите Preview

Положили @State в неправильное место @State должен быть свойством view, а не локальной переменной внутри body

Сразу строите сложную архитектуру Для первого экрана не нужен MVVM. Сначала поймите Text, Button, VStack и @State

Как SwiftUI пересчитывает экран

SwiftUI view описывает, как экран должен выглядеть для текущего состояния. Когда меняется @State, SwiftUI заново вычисляет body и сравнивает новое описание UI с прежним. Вам не нужно вручную искать label и менять ему текст

В счетчике это видно прямо:

@State private var count = 0

var body: some View {
    Text("Count: \(count)")
    Button("Add") {
        count += 1
    }
}

Кнопка меняет count, а Text показывает новое значение. Между ними нет ручного вызова reload, refresh или setText

Это главная привычка SwiftUI: вы описываете зависимость интерфейса от состояния. Если состояние верное, UI сам приходит к нужному виду

Разбиваем body на маленькие части

Когда экран растет, body быстро становится шумным. Первый безопасный шаг — вынести куски в computed properties:

var titleView: some View {
    Text("SwiftUI counter")
        .font(.title)
}

var controls: some View {
    Button("Add") {
        count += 1
    }
}

Потом собрать:

var body: some View {
    VStack(spacing: 16) {
        titleView
        Text("Count: \(count)")
        controls
    }
    .padding()
}

Так вы не вводите архитектуру раньше времени, но уже держите экран читаемым. Это хороший промежуточный прием перед отдельными child views и @Binding

Добавляем второе состояние

Попробуйте добавить имя:

@State private var name = "Dinar"

И кнопку:

Button("Change name") {
    name = name == "Dinar" ? "Swift learner" : "Dinar"
}

Покажите текст:

Text("Student: \(name)")

Теперь экран зависит от двух состояний: count и name. Это все еще нормально для первого урока. Но если состояний становится много, появляется смысл выносить части экрана и думать о модели данных

Проверка в Preview и Simulator

Preview удобен для быстрой проверки layout, но иногда он зависает или показывает старое состояние. Если сомневаетесь, запустите приложение в Simulator. Для учебного экрана правило простое:

  1. Preview показывает верстку
  2. Simulator проверяет реальный запуск
  3. Console помогает читать ошибки

Если Preview не обновляется, не переписывайте код наугад. Сначала сделайте clean build или перезапустите preview. Если Simulator собирает проект нормально, проблема может быть именно в preview canvas

Маленькая визуальная доработка без ухода в дизайн

Чтобы экран выглядел не как голая проверка кнопки, добавьте пару модификаторов:

Text("Count: \(count)")
    .font(.largeTitle)
    .fontWeight(.semibold)

Button("Add") {
    count += 1
}
.buttonStyle(.borderedProminent)

Модификаторы в SwiftUI читаются сверху вниз: берется view и к нему последовательно применяются настройки. Это не CSS и не XML-разметка, но идея похожа: вы описываете внешний вид декларативно

Не пытайтесь сразу сделать идеальный интерфейс. Для первого экрана достаточно, чтобы текст был читаемым, кнопка была заметной, а изменение состояния проверялось без догадок

Домашка: счетчик с ограничением

Сделайте так, чтобы счетчик не уходил ниже нуля:

Button("Minus") {
    if count > 0 {
        count -= 1
    }
}

Дополнительная задача: если count == 0, показывайте текст Minimum reached. Так вы потренируете условный UI и увидите, как SwiftUI реагирует на изменение состояния

Еще одна проверка: добавьте кнопку Reset, которая возвращает счетчик в ноль. Если текст, условное сообщение и кнопки синхронно обновляются после каждого нажатия, базовая модель @State действительно понятна

Что может быть еще интересно по этой теме

SwiftUI заменяет UIKit? SwiftUI активно используется для новых интерфейсов, но UIKit остается в большом количестве проектов. Новичку можно начинать со SwiftUI

Почему view является struct? SwiftUI работает с декларативным описанием UI и состоянием. Struct хорошо подходит для описания значения view

Когда нужен @Binding? Когда состояние хранится в родительском view, но дочерний view должен его менять

Что дальше после первого экрана? Разберите @Binding, чтобы счетчик или переключатель можно было вынести в отдельный компонент

Что почитать дальше по Swift

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x