Двусторонняя привязка в Swift Combine (UIKit)

#ios #swift #mvvm #uikit #combine

#iOS #swift #mvvm #uikit #объединить

Вопрос:

У меня есть a UITableViewCell , которые содержат a UISwitch . У этой клетки есть своя собственная SwitchCellViewModel . Допустим, он содержит некоторое Bool значение (включено или отключено). И ViewController является тем, кто содержит UITableView , создает viewModel для ячейки и устанавливает с ней ячейку.

Я хочу достичь:

  1. На уровне ячейки: изменяйте состояние пользовательского интерфейса всякий раз, когда изменяется значение свойства bool ViewModel (без перезагрузки TableView, конечно).
  2. На уровне ViewController: обрабатывать изменение состояния пользовательского интерфейса (пользователем).

Следующий вариант использования: ячейка показывает некоторую опцию, которую можно отключить или включить. Это действие переходит на серверную часть, и после того, как я получу ответ с результатом (включено или отключено на серверной части), я должен снова синхронизировать состояние представления с обновленными данными.

Я понимаю, как подписаться на изменение значения свойства на уровне ячейки, поэтому, когда я изменяю его в ViewModel из ViewController, он сразу обновляет представление ячейки. Но я не уверен, как справиться с обратным действием от UISwitch ViewController к ViewController.

Достижимо ли это с помощью одного @Published свойства bool в ViewModel, или у меня должно быть 2 отдельные вещи для этого двунаправленного случая.

Мне кажется очень глупым, что я должен предоставлять отдельный Publisher для этой цели, поскольку у меня уже есть @Published свойство в viewmodel, о котором должен быть уведомлен контроллер представления, так почему бы мне не использовать его. Но если я использую только один, то будет так, что ViewController установит @Published var в ViewModel , сама ячейка обработает его и настроит пользовательский интерфейс, но ViewController также немедленно получит об этом событие, поскольку на него подписана.

Комментарии:

1. Зачем вам нужен @Published ? Планируете ли вы взаимодействовать с SwiftUI? Если да, можете ли вы предоставить нам более подробную информацию? Если нет, то вы можете вообще не использовать оболочки свойств SwiftUI.

Ответ №1:

@Published это односторонний поток данных — он, наряду с ObservableObject , синтезирует объединенную цепочку издателей, которая отправляет обновления (полудуплексный или односторонний), когда значения «изменятся». Он не отправляет измененное значение, а только сигнал о том, что что-то изменилось.

Чтобы вернуть поток данных обратно в модель, вам нужно что-то вызвать или запустить этот обратный поток данных при активации пользовательского интерфейса. Это может быть так же просто, как метод обратного вызова, чтобы обновить модель, в которой вы сохраняете состояние, — и именно с этого я обычно начинаю.