Что такое Binding в SwiftUI?

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

Ответ

Binding в SwiftUI — это механизм, обеспечивающий двустороннюю связь (two-way binding) между значением, хранящимся в источнике истины (source of truth), и представлением (View), которое это значение читает и изменяет. Это не само значение, а ссылка на него, позволяющая как читать, так и записывать.

Для чего используется? Для создания интерактивных элементов управления (TextField, Toggle, Slider), которые должны не только отображать состояние, но и иметь возможность его изменять, с последующим автоматическим обновлением интерфейса.

Как создается Binding? Обычно используется префикс $ перед свойством, обернутым в property wrapper, который предоставляет Binding (например, @State, @StateObject, @ObservedObject, @EnvironmentObject).

Пример:

struct ContentView: View {
    // @State - источник истины для примитивного значения
    @State private var username: String = ""
    @State private var isDarkMode: Bool = false

    var body: some View {
        VStack {
            // TextField МЕНЯЕТ значение username.
            // $username создает Binding<String> для связи.
            TextField("Enter your name", text: $username)
                .textFieldStyle(.roundedBorder)

            // Текст только ЧИТАЕТ значение username.
            Text("Hello, (username)!")

            // Toggle МЕНЯЕТ значение isDarkMode.
            Toggle("Dark Mode", isOn: $isDarkMode)
        }
        .padding()
    }
}

Создание кастомного Binding (редкий случай): Иногда нужно создать Binding с кастомной логикой чтения/записи.

let customBinding = Binding(
    get: { /* логика возврата значения */ },
    set: { newValue in /* логика обработки нового значения */ }
)

Ключевые property wrappers, предоставляющие Binding:

  • @State: Для примитивных типов или структур, принадлежащих конкретному View.
  • @StateObject / @ObservedObject: Для ссылочных типов, соответствующих протоколу ObservableObject.
  • @EnvironmentObject: Для общих данных, переданных в environment.
  • @Binding: Для получения Binding от родительского View (делегирование источника истины наверх).

Принцип работы: Когда элемент управления через Binding изменяет значение, SwiftUI помечает зависимые View как «грязные» и перерисовывает их, обеспечивая реактивность интерфейса.