如何在 RxSwift 中将多个数据模型绑定到 TableView
How to bind multiple data models to TableView in RxSwift
我正在研究RxSwift。
但这很难,所以我 post 一个问题。
情况:
我想在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))
}
}
}
}
ViewController :
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
请帮助我....
我只需要实现非常像这样的东西。这是我所做的:
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。 但这很难,所以我 post 一个问题。
情况: 我想在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))
}
}
}
}
ViewController :
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
请帮助我....
我只需要实现非常像这样的东西。这是我所做的:
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)
}