В чем разница между View в SwiftUI и UIView в UIKit?

«В чем разница между View в SwiftUI и UIView в UIKit?» — вопрос из категории SwiftUI, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

View в SwiftUI и UIView в UIKit — это фундаментально разные подходы к описанию пользовательского интерфейса в iOS.

Сравнительная таблица:

Характеристика View (SwiftUI) UIView (UIKit)
Тип данных Value type (struct, реализует протокол View). Reference type (class, наследник UIResponder).
Парадигма Декларативная. Описываете как должен выглядеть UI в зависимости от состояния. Императивная. Указываете как изменять UI в ответ на события.
Жизненный цикл Управляется фреймворком. Нет прямых аналогов layoutSubviews() или draw(). Явный жизненный цикл с методами (init, layoutSubviews, draw, deinit).
Обновление UI Автоматическое. При изменении @State, @ObservedObject SwiftUI перерисовывает зависящие от них View. Ручное. Вызываете методы вроде setNeedsLayout() или setNeedsDisplay(), чтобы сообщить системе о необходимости обновления.
Макет (Layout) Используются модификаторы и стеки (VStack, HStack), которые описывают отношения между View. Используются Auto Layout constraints или расчет фреймов вручную (frame).
Производительность Высокая за счет оптимизаций фреймворка (diffing, постоянные идентификаторы). Требует ручной оптимизации (переиспользование ячеек, кэширование).
Доступ к слоям Нет прямого доступа к CALayer. Стилизация через модификаторы. Прямой доступ к layer для анимаций, теней, скругления углов.

Примеры:

Простая View в SwiftUI:

struct ContentView: View {
    @State private var isOn: Bool = false // Состояние

    var body: some View {
        VStack {
            Text("Hello, SwiftUI!")
                .font(.title)
                .foregroundColor(isOn ? .blue : .gray)

            Toggle("Switch", isOn: $isOn) // Двусторонняя привязка к состоянию
        }
        .padding() // Модификатор
    }
}
// UI обновится автоматически при изменении `isOn`.

Аналогичная UIView в UIKit:

class ContentView: UIView {
    let label = UILabel()
    let toggle = UISwitch()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }

    private func setupUI() {
        // 1. Создание и настройка
        label.text = "Hello, UIKit!"
        label.font = .systemFont(ofSize: 24)
        addSubview(label)
        addSubview(toggle)

        // 2. Ручная установка констрейнтов (Auto Layout)
        label.translatesAutoresizingMaskIntoConstraints = false
        toggle.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            label.centerXAnchor.constraint(equalTo: centerXAnchor),
            label.topAnchor.constraint(equalTo: topAnchor, constant: 20),
            toggle.centerXAnchor.constraint(equalTo: centerXAnchor),
            toggle.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 20)
        ])

        // 3. Ручная привязка события
        toggle.addTarget(self, action: #selector(toggleChanged), for: .valueChanged)
    }

    @objc func toggleChanged() {
        // 4. Ручное обновление UI в ответ на событие
        label.textColor = toggle.isOn ? .blue : .gray
    }
}

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