iOS:如何使用 RxSwift 删除 TableView 中的单元格

标签 ios iphone swift rx-swift

我刚刚开始使用 RxSwift 并面临一些挑战。我已经创建了具有多个部分的表格 View ,并且能够点击并获取详细信息。但是,如果我尝试删除任何特定的单元格,它就不起作用。我不确定我在 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)
  }

最佳答案

问题

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)

现在应该可以删除了。

关于iOS:如何使用 RxSwift 删除 TableView 中的单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52050486/

相关文章:

ios - 如何使用 Swift 访问 healthkit 中锻炼的元数据

iphone - 反转 UIWebView 或 UITextView 中的颜色

ios - 我们可以滚动 UIStackView 吗

ios - 将 RPPreviewController 中的视频保存到特定位置而不是保存到相机胶卷?

ios - 允许在 PerformBatchUpdates 期间进行用户交互

swift - 如何获取 Double 小数点后的第一个数字?

ios - 在 Xcode 中拥有多个产品变体的最佳方式是什么?

ios - 如何在一个 UIViewController 中维护两个 api?

ios - 设置 UIPageViewController.dataSource 时发送到实例的无法识别的选择器?

ios - animationControllerForPresentedController 和 animateTransition 之间的自定义过渡动画未知延迟