如何在 RxSwift 中将多个数据模型绑定到 TableView

Posted

技术标签:

【中文标题】如何在 RxSwift 中将多个数据模型绑定到 TableView【英文标题】:How to bind multiple data models to TableView in RxSwift 【发布时间】:2019-09-06 09:14:58 【问题描述】:

我正在学习 RxSwift。 但这很困难,所以我发布了一个问题。

情况: 我想在tableView中显示字符的信息。 角色有物品信息和头像信息。 (有两个 API。)

问题: 我成功在tableView中显示了一个数据模型(项目信息)。 但我不知道如何将两个或多个模型绑定到 tableView。

这是我将一个模型绑定到 tableView 时的代码。

视图模型:

let characterDetail = PublishSubject<CharacterDetailResp>()
var characterDetailInfo : CharacterDetailResp = CharacterDetailResp()
let error : PublishSubject<CharacterDetailError> = PublishSubject()

func requestData() 
        let URL : String = "\(baseUrl)/servers/characterName/"

        AF.request(URL, method: .get, parameters:nil, encoding: JSONEncoding.default).responseObject 
        (response : DataResponse<CharacterDetailResp>) in

        switch response.result 
        case .success:
            self.characterDetailInfo = response.value!
            self.characterDetail.onNext(self.characterDetailInfo)

        case .failure(let err):
            if err.localizedDescription == "The Internet connection appears to be offline." 
                self.error.onNext(.internetError("Please Check Internet"))
            
            else 
                self.error.onNext(.serverMessage(err.localizedDescription))
            
        
    


视图控制器:

var characterDetailViewModel = ViewModel()
let characterDetail = PublishSubject<CharacterDetailResp>()
let disposeBag = DisposeBag()

func setupBindings() 
        characterDetailViewModel
            .error
            .observeOn(MainScheduler.instance)
            .subscribe(onNext:  (error) in
                switch error 
                case .internetError(let message):
                    print("Error : \(message)")
                case .serverMessage(let message):
                    print("Warning : \(message)")
                
            )
            .disposed(by: disposeBag)

        tableView.register(UINib(nibName: "CharacterCell", bundle: nil), forCellReuseIdentifier: String(describing: CharacterCell.self))

        characterDetailViewModel
            .characterDetail
            .observeOn(MainScheduler.instance)
            .bind(to: tableView.rx.items(cellIdentifier: "CharacterCell", cellType: CharacterCell.self)) 
                (row, characterDetail, cell) in
                cell.character = characterDetail
            
            .disposed(by: disposeBag)
    

我想知道如何将两个或多个 API 模型绑定到 TableView

请帮帮我....

【问题讨论】:

你想要什么?例如,您是否需要在表格视图中显示两个不同的单元格?或者它只是一些用标题包裹的单元格?请详细说明。 【参考方案1】:

我只需要实现一些非常类似的东西。这是我所做的:

final class SearchDataSource: NSObject, RxTableViewDataSourceType, UITableViewDataSource 
    func tableView(_ tableView: UITableView, observedEvent: Event<SearchResult>) 
        switch observedEvent 
        case .next(let result):
            searchResult = result
            tableView.reloadData()
        case .error(let error):
            fatalError(error.localizedDescription)
        case .completed:
            break
        
    

    func numberOfSections(in tableView: UITableView) -> Int 
        return 2
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        switch section 
        case 0:
            return searchResult.titles.count
        case 1:
            return searchResult.bodies.count
        default:
            fatalError("too many sections")
        
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        switch indexPath.section 
        case 0:
            let segment = searchResult.titles[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "Title", for: indexPath) as! TitleTableViewCell
            cell.configure(with: segment)
            return cell
        case 1:
            let segment = searchResult.bodies[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "Body", for: indexPath) as! BodyTableViewCell
            cell.configure(with: segment)
            return cell
        default:
            fatalError("too many sections")
        
    

    var searchResult = SearchResult(titles: [], bodies: [])


final class TitleTableViewCell: UITableViewCell 
    func configure(with segment: TitleSegment)  


final class BodyTableViewCell: UITableViewCell 
    func configure(with segment: BodySegment)  


struct SearchResult 
    let titles: [TitleSegment]
    let bodies: [BodySegment]


struct TitleSegment 
    let sectionID: Int
    let title: String


struct BodySegment 
    let sectionTitle: String
    let sectionID: Int
    let text: String

下面是如何使用它:

override func viewDidLoad() 
    super.viewDidLoad()

    let viewModel = viewModelFactory(self)

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

【讨论】:

我没试过,但我知道这接近正确答案。谢谢你的回答!

以上是关于如何在 RxSwift 中将多个数据模型绑定到 TableView的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift 从一个创建多个 Observable

使用 RxSwift 将多个 UITextField 绑定到类道具

如何使用 RxSwift 和 RxSwiftDataSources 将表视图与表示不同数据类型的多个部分绑定?

如何使用 RXSwift 将 Object 的属性绑定到 UIlabel?

IOS RxSwift中UISearch栏文本和视图模型属性之间的两种方式绑定

如何在MVVM架构中使用RxSwift发送参数来查看模型?