代码之家  ›  专栏  ›  技术社区  ›  Kashif Jilani

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

  •  0
  • Kashif Jilani  · 技术社区  · 6 年前

    我刚开始与RXSwift合作,并面临一些挑战。我已经创建了具有多个部分的TableView,并且能够点击并获取详细信息。但是,如果我尝试删除任何特定的单元格,它将不起作用。我不知道我在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 回复  |  直到 6 年前
        1
  •  1
  •   E-Riddie    6 年前

    问题

    tableView.rx.itemDeleted 触发包含 indexPath ,发生删除操作的位置。数据的更改应该由您来处理。您没有得到任何更新,因为您没有更改任何内容,您只是在打印 索引路径 出来。

    解决方案

    因为你用的是 viewModel.getUsers() 它给你一个 Observable<[SectionModel<String, User>]> 从你的代码判断。您还应该在 viewModel 它将用于在特定的 索引路径 .

    为了实现这一点,您需要将元素存储在 BehaviorSubject . 这将保留数据的当前值,更新后,它将向订阅它的数据发出新的数据。

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

    当您初始化 视图模型 ,您需要用数据填充此主题,这样做:

    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()
    }
    

    你的最后一步 视图模型 ,将实现 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)
    

    现在可以删除了。