Reputation: 129
I have a view model that has an element that returns an observable array after calling an API.
I then find that result to a table view to display it. The problem I am having is how to call the detail view controller on the specific cell that is clicked. I bound the results with:
let queryResults = eventsViewModel.mainTableItems
queryResults
.bind(to: collectionView.rx.items) { collectionView, row, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: IndexPath(row: row, section: 0)) as! EventCell
cell.heroID = "heroCellID"
cell.restaurantNameLabel.text = item.name
cell.restaurantDetailLabel.text = item.location
cell.timeLabel.text = item.date
cell.restaurantImageView.kf.setImage(with: URL(string: item.image))
return cell
}
.addDisposableTo(disposeBag)
I have no way to access the specific element in this observable array that was clicked. It says an Observable array cannot have subscript.
This is the code that says that:
vc.festival = queryResults.value[indexPath.row]
I am still new to RxSwift and I am struggling to understand this.
Upvotes: 3
Views: 2594
Reputation:
Depending on the complexity of your app, as Daniel suggested- creating a high level coordinator object may be the best option. One simple option is to create a property in eventsViewModel
and assign a value to it from within tableView.rx.itemSelected
. Then when you prepare for segue, you can retrieve object from eventsViewModel
, like so:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "identifier" {
let detailVC = segue.destination as! DetailViewController
if let selectedItem = eventsViewModel.item {
detailVC.viewModel = DetailViewModel(item: selectedItem)
}
}
}
probably not the best solution but it does work as intended.
Upvotes: 0
Reputation: 33967
This really is the million dollar question, and something that has a lot of different answers and none are really simple, even without using RxSwift. The short answer is, it depends on how your app is architected.
First thing, if you haven't already realized, is that you find out which item was selected with tableView.rx.itemSelected
.
IMHO, view controllers should be independent of each other so the one thing you don't want to do is create or segue to the detail view controller from this one. There should be some sort of coordinator object that subscribes to itemSelected
and is in charge of deciding where to go from there.
Here are some good articles to get you on the right track:
http://rasic.info/a-different-take-on-mvvm-with-swift/
In this article, Mr. Rasic talks about a class that he calls the Scene
which is in charge of creating the view controller and its view mode, attaching them and then deciding where to go from there.
http://khanlou.com/2015/01/the-coordinator/
In this article, Mr. Khanlou talks about a class that he calls the Coordinator
. He doesn't use Rx, instead he uses delegates, but it's pretty easy to see how it would relate.
https://talk.objc.io/episodes/S01E05-connecting-view-controllers
This is a video where the objc.io team creates an App
class that takes care of view controller navigation. They use closures here instead of Rx, but again the correspondence should be obvious.
Upvotes: 2