0Pricing
Swift Academy · Урок

Шаблон Coordinator для взаимодействия с делегатами

Используйте makeCoordinator(), чтобы передавать обратные вызовы делегатов UIKit в SwiftUI.

«Шаблон Coordinator для взаимодействия с делегатами» — бесплатный урок Swift Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Зачем нужны координаторы?

Делегатам UIKit требуется ссылка на объект. Типы-значения SwiftUI не могут быть делегатами. Координатор служит связующим звеном.

struct ImagePicker: UIViewControllerRepresentable {
  @Binding var image: UIImage?
  // Coordinator will be the UIImagePickerControllerDelegate
}

makeCoordinator()

Реализуйте makeCoordinator(), возвращающий экземпляр Coordinator. SwiftUI вызывает этот метод до makeUIView/Controller.

func makeCoordinator() -> Coordinator {
  Coordinator(self)
}

Класс Coordinator

Coordinator обычно является классом (для совместимости с делегатами), который хранит ссылку на родительскую обёртку представления.

class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
  var parent: ImagePicker
  init(_ parent: ImagePicker) { self.parent = parent }
}

Назначение делегата

В makeUIViewController назначьте context.coordinator делегатом.

func makeUIViewController(context: Context) -> UIImagePickerController {
  let picker = UIImagePickerController()
  picker.delegate = context.coordinator
  return picker
}

Реализация методов делегата

Обратные вызовы делегата в Coordinator передают изменения обратно в SwiftUI, изменяя привязки родительской обёртки.

func imagePickerController(
  _ picker: UIImagePickerController,
  didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]
) {
  parent.image = info[.originalImage] as? UIImage
  picker.dismiss(animated: true)
}

Обратный вызов отмены

Реализуйте делегат отмены, чтобы закрыть средство выбора и при необходимости уведомить SwiftUI.

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
  picker.dismiss(animated: true)
}

Источник данных через Coordinator

Coordinator также может реализовывать протоколы источника данных, например UITableViewDataSource, для табличных и коллекционных представлений.

class Coordinator: NSObject, UITableViewDataSource {
  var parent: MyTableView
  init(_ p: MyTableView) { parent = p }
  func tableView(_ tv: UITableView, numberOfRowsInSection s: Int) -> Int { parent.items.count }
  func tableView(_ tv: UITableView, cellForRowAt ip: IndexPath) -> UITableViewCell {
    let cell = tv.dequeueReusableCell(withIdentifier: "cell", for: ip)
    cell.textLabel?.text = parent.items[ip.row]
    return cell
  }
}

Обновление Coordinator

При повторной отрисовке SwiftUI вызывается updateUIViewController. При необходимости обновите ссылку координатора на новую родительскую обёртку.

func updateUIViewController(_ vc: UIImagePickerController, context: Context) {
  context.coordinator.parent = self
}

Несколько делегатов

Координатор может соответствовать нескольким протоколам делегатов, централизуя все обратные вызовы UIKit.

class Coordinator: NSObject,
  UIScrollViewDelegate,
  UITextViewDelegate,
  UISearchBarDelegate { ... }

Coordinator и @Binding

Используйте @Binding для простой передачи значений, а Coordinator — когда UIKit требует ссылки на делегат.

// Simple: @Binding var text: String -> updateUIView writes uiView.text = text
// Complex: coordinator mediates UITextViewDelegate -> parent.text = textView.text

Жизненный цикл Coordinator

Coordinator создаётся один раз для каждой обёртки представления и существует, пока эта обёртка находится в дереве представлений.

// makeCoordinator called once → stable delegate reference
// updateUIView called many times → push state changes

Проверка знаний

Какой метод необходимо реализовать в UIViewControllerRepresentable, чтобы создать объект, связывающий делегат с представлением?

Итоги урока

Шаблон Coordinator: реализуйте makeCoordinator(), создайте класс, соответствующий протоколам делегатов UIKit, назначьте его через context.coordinator в makeUIViewController и передавайте изменения обратно в SwiftUI через привязки, хранящиеся в parent.

Часто задаваемые вопросы

Урок «Шаблон Coordinator для взаимодействия с делегатами» бесплатный?

Да — полный текст урока «Шаблон Coordinator для взаимодействия с делегатами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Шаблон Coordinator для взаимодействия с делегатами»?

Используйте makeCoordinator(), чтобы передавать обратные вызовы делегатов UIKit в SwiftUI. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Шаблон Coordinator для взаимодействия с делегатами»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. UIViewRepresentable: обёртка для представлений UIKit
  2. Шаблон Coordinator для взаимодействия с делегатами
  3. UIViewControllerRepresentable
  4. UIHostingController: SwiftUI внутри UIKit
← Назад к Swift Academy