Как переместить логику для отображения UITableViewRowAction из метода делегата в View Model (архитектура MVVM)

Я научился использовать RxSwift и RxDataSource для отделения бизнес-логики от View Controller (используя MVVM).

Предположим, я хочу создать табличное представление, как в приложении "Почта" в iOS, когда пользователь проводит пальцем влево, там есть кнопка "Удалить" и кнопка "Еще".

В нормальном MVC я должен реализовать метод делегата editActionsForRowAt,

public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?

        var swipeActions = [UITableViewRowAction]()
        let removeAction = UITableViewRowAction(style: .destructive, title: "Delete") { [weak self] (action, indexPath) in
            guard let strongSelf = self else { return }
            strongSelf.deleteBankAccountTrigger.onNext(indexPath)
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
        swipeActions.append(removeAction)

        if *cellIsNotDefault* {
            let makeDefaultAction = UITableViewRowAction(style: .default, title: "Make Default") { [weak self] (action, indexPath) in
                guard let strongSelf = self else { return }
                strongSelf.makeBankAccountDefaultTrigger.onNext(indexPath)
            }

            makeDefaultAction.backgroundColor = UIColor.lightGray
            swipeActions.append(makeDefaultAction)
        }

        return swipeActions

Я не знаю, как переместить логику cellIsNotDefault из делегата в ViewModel. Потому что я думаю, что логика, чтобы показать / скрыть SwipeAction Кнопка должна быть во ViewModel.

Любое предложение приветствуется.

Спасибо.

Обновить:

Я пытался использовать RxDataSources, но до сих пор не понял, какие действия нужно выполнить смахиванием. Для удаления действия я могу использовать tableView.rx.itemDeleted способ подписаться на него. Но если я хочу подписаться на пользовательское действие Swipe (например, мое действие Make Default). Как это сделать?

1 ответ

Решение

Прежде всего, viewModel должен содержать только данные, которые отображаются конкретным представлением. Поэтому я не уверен, должна ли viewModel содержать информацию о поведении вашего представления (в этом случае это означает, что в вашей ячейке есть какое-то действие). Может быть, я бы включил эту логику в саму модель. Я думаю, что вы получаете из API что-то вроде isBankAccountDefault, Если вы не получили этот атрибут напрямую из API, и вам нужна логика для его определения. Вы можете создать вычисляемое свойство внутри вашей модели и поместить туда * cellIsNotDefault * логику.

Но если вы настаиваете на том, чтобы это было в viewModel, вы можете создать свойство Bool isBankAccountDefault во ViewModel. Затем вы поместите логику * cellIsNotDefault * в форматтер, который создает эту viewModel, и установите isBankAccountDefault значение в соответствии с * cellIsNotDefault * логика.

Другие вопросы по тегам