I create a View Controller that contains a UITableView and each UITableViewCell contains a UICollectionView. My problem is that I can't have a different result on every CollectionView. I parse data with JSON. I have a static array but it looks like its empty.
In cellForItemAt, I get an error: Index out of range.
Here is my ViewController
import UIKit
class HomeScreenCategoriesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var moviesCategories = ["Popular", "Now Playing", "Latest", "Top Rated", "Upcoming"]
var popularMovies = MovieModel()
var nowPlayingMovies = MovieModel()
static var movies: [MovieModel] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.rowHeight = 130
tableView.tableFooterView = UIView()
parsePopularMovies()
parseNowPlayingMovies()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "\(moviesCategories[section])"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "HomeScreenMovieTableViewCell", for: indexPath) as? HomeScreenCategoriesTableViewCell
{
return cell
}
return UITableViewCell()
}
func parsePopularMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let tempMovies = try
JSONDecoder().decode(MovieModel.self, from: data)
self.popularMovies.page = tempMovies.page
self.popularMovies.total_results = tempMovies.total_results
self.popularMovies.total_pages = tempMovies.total_pages
self.popularMovies.results = tempMovies.results
for i in 0..<(self.popularMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (self.popularMovies.results?[i].poster_path)!!
let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.popularMovies.results?[i].backdrop_path)!!
self.popularMovies.results?[i].poster_path = tempPosterPath
self.popularMovies.results?[i].backdrop_path = tempBackDropPath
HomeScreenCategoriesViewController.movies.append(self.popularMovies)
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
func parseNowPlayingMovies() {
let jsonUrlString = "URLwithMyAPIkey"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let tempMovies = try
JSONDecoder().decode(MovieModel.self, from: data)
self.nowPlayingMovies.page = tempMovies.page
self.nowPlayingMovies.total_results = tempMovies.total_results
self.nowPlayingMovies.total_pages = tempMovies.total_pages
self.nowPlayingMovies.results = tempMovies.results
for i in 0..<(self.nowPlayingMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].poster_path)!!
//let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].backdrop_path)!!
self.nowPlayingMovies.results?[i].poster_path = tempPosterPath
HomeScreenCategoriesViewController.movies.append(self.nowPlayingMovies)
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()
}
}
and here is my TableViewCell
import UIKit
class HomeScreenCategoriesTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet var collectionView: UICollectionView!
var sectionIndex:Int?
static var movies: [MovieModel] = []
override func awakeFromNib() {
super.awakeFromNib()
self.collectionView.delegate = self
self.collectionView.dataSource = self
DispatchQueue.main.async {
self.collectionView.reloadData()
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeScreenMovieTableViewCell", for: indexPath) as! HomeScreenCategoriesTableViewCell
cell.sectionIndex = indexPath.section
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeScreenMovieCell", for: indexPath) as! HomeScreenCategoriesCollectionViewCell
cell.test.text = HomeScreenCategoriesTableViewCell.movies[collectionView.tag].results?[indexPath.row].title!
return cell
}
}
My model is this:
struct MovieResults: Codable, Equatable {
let id: Int?
let title: String?
let overview: String?
let adult: Bool?
let original_language: String?
var poster_path: String?
var backdrop_path: String?
let vote_average: Float?
let release_date: String?
}
struct MovieModel: Codable {
var page: Int?
var total_results: Double?
var total_pages: Int?
var results: [MovieResults]?
}
I tried to follow this instruction (How to get section of UITableView from inside a child UICollectionview) but I can'tâ find a solution
What am I doing wrong?