iOS: как удалить ячейку в табличном представлении с помощью RxSwift - PullRequest
0 голосов
/ 28 августа 2018

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

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, User>>(
      configureCell: { (_, tv, indexPath, element) in
        let cell = tv.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = string
        cell.textLabel?.numberOfLines = 0
        return cell
      },
      titleForHeaderInSection: { dataSource, sectionIndex in
        return dataSource[sectionIndex].model
      }
    )
    dataSource.canEditRowAtIndexPath = { dataSource, indexPath  in
      return true
    }

    viewModel.getUsers()
      .bind(to: tableView.rx.items(dataSource: dataSource))
      .disposed(by: disposeBag)

    tableView.rx
      .itemSelected
      .map { indexPath in
        return (indexPath, dataSource[indexPath])
      }
      .subscribe(onNext: { pair in
        print("Tapped \(pair.1) @ \(pair.0)")
      })
      .disposed(by: disposeBag)


    tableView.rx.itemDeleted
      .subscribe{
        print($0)
      }
      .disposed(by: disposeBag)

    tableView.rx
      .setDelegate(self)
      .disposed(by: disposeBag)
  }

1 Ответ

0 голосов
/ 29 августа 2018

Выпуск

tableView.rx.itemDeleted запускает событие, содержащее indexPath, где произошло действие удаления. Изменение ваших данных должно быть обработано вами. Вы не получаете никаких обновлений, потому что вы ничего не меняете, вы просто печатаете indexPath.

Решение

Поскольку вы используете viewModel.getUsers(), который возвращает вам Observable<[SectionModel<String, User>]>, исходя из вашего кода. Вам также следует ввести метод для viewModel, который будет использоваться для удаления элемента с определенной indexPath.

Чтобы достичь этого, вам нужно иметь хранилище ваших элементов в BehaviorSubject. Это будет содержать текущее значение данных, и при обновлении оно будет отправлять новые данные тем, которые подписались на него.

let sectionListSubject = BehaviorSubject(value: [SectionModel<String, User>]())

Когда вы инициализируете ваш viewModel, вам нужно заполнить эту тему данными, сделав так:

sectionListSubject.onNext([
            SectionModel(model: "First section", items: [
                User(),
                User(),
                User()
                ]),
            SectionModel(model: "Second section", items: [
                User(),
                User(),
                User()
                ])
            ])

Тогда ваш getUsers() метод должен выглядеть следующим образом:

func getUsers() -> Observable<[SectionModel<String, User>]> {
    return sectionListSubject.asObservable()
}

Последний шаг на вашем viewModel, это реализация removeItem(at:)

func removeItem(at indexPath: IndexPath) {
    guard var sections = try? sectionListSubject.value() else { return }

    // Get the current section from the indexPath
    var currentSection = sections[indexPath.section]

    // Remove the item from the section at the specified indexPath
    currentSection.items.remove(at: indexPath.row)

    // Update the section on section list
    sections[indexPath.section] = currentSection

    // Inform your subject with the new changes
    sectionListSubject.onNext(sections)
}

Теперь, когда у вас есть кодовая база, вам просто нужно изменить:

tableView.rx.itemDeleted
    .subscribe(onNext: { self.viewModel.removeItem(at: $0) })
    .disposed(by: disposeBag)

Удаление должно работать.

...