gpt4 book ai didi

swift - 如何在子 UICollectionView 上获取 UITableView 的一部分

转载 作者:行者123 更新时间:2023-11-28 13:29:52 24 4
gpt4 key购买 nike

我创建了一个包含 UITableView 的 View Controller ,每个 UITableViewCell 都包含一个 UICollectionView。我的问题是我不能在每个 CollectionView 上得到不同的结果。我用 JSON 解析数据。我有一个静态数组,但它看起来是空的。

In cellForItemAt, I get an error: Index out of range.

这是我的 View Controller

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

}

}

这是我的 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
}

}

我的模型是这样的:

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]?
}

我试着按照这个说明(How to get section of UITableView from inside a child UICollectionview)但是我找不到解决方案

我做错了什么?

最佳答案

这里有几个问题:

  1. 模型命名您使用的数据模型对象令人困惑。 MovieModel听起来它应该代表一部电影。但是看看解析函数,

            self.nowPlayingMovies.page = tempMovies.page
    self.nowPlayingMovies.total_results = tempMovies.total_results
    self.nowPlayingMovies.total_pages = tempMovies.total_pages
    self.nowPlayingMovies.results = tempMovies.results

    看起来该对象中有多个条目。它可能应该被称为MovieCategoryModel . HomeScreenCategoriesTableViewCell应该有一个看起来像这样的模型:

    var movieCategory: MovieCategoryModel!

因为你要在里面放不同的电影 不同的部分,movieCategory属性不应该是 static .

  1. cellForItemAt indexPath 在此方法中,您尝试使用有关电影的数据配置单元格 UI。但是 HomeScreenCategoriesTableViewCell 的属性从未有人居住过。

  2. numberOfItemsInSection这应该返回该部分中的电影数量。您的代码返回 5 - 这是某个任意数字。这就是错误的问题。你应该返回 movieCategory.total_results

  3. cellForRowAt indexPathHomeScreenCategoriesViewController当你出队时HomeScreenMovieTableViewCell ,你需要将电影传递给那个单元格,这样它就会有数据来呈现。您需要执行以下操作:

    if section == 0 {
    cell.movieCategory = popularMovies
    } else if section == 1 {
    cell.movieCategory = nowPlayingMovies
    }

  4. 一般来说,从解析代码来看,需要为每个类别分别保存电影。这样,在 tableView 委托(delegate)方法中,您可以轻松获取该部分所需的数据。

  5. 解析代码也需要一些工作,因为我可以看到您正在循环遍历对象中包含的项目

    for i in 0..<(self.nowPlayingMovies.results?.count ?? 0)

但在同一个循环中将整个对象添加到数组

`HomeScreenCategoriesViewController.movies.append(self.nowPlayingMovies)`

根据提供的额外信息进行编辑:

MovieResults对于表示单个电影的对象来说,这是一个非常令人困惑的名称。我建议将其更改为 Movie .那么MovieModel - 包含多部电影的对象将是 MovieCategory .也许将该类别的标题存储在对象本身中也是一个好主意?

模型

struct Movie: 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 MovieCategory: Codable {
var title: String?
var page: Int?
var total_results: Double?
var total_pages: Int?
var results: [Movie]?
}

View Controller

import UIKit

class HomeScreenCategoriesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!
var moviesCategories: [MovieCategory] = []


override func viewDidLoad() {
super.viewDidLoad()

tableView.rowHeight = 130
tableView.tableFooterView = UIView()
parsePopularMovies()
parseNowPlayingMovies()

}

func numberOfSections(in tableView: UITableView) -> Int {
return moviesCategories.count
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let category = moviesCategories[section]
return category.title
}

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
{
cell.movieCategory = moviesCategories[indexPath.section]
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 {
var popularMovies = try
JSONDecoder().decode(MovieCategory.self, from: data)
popularMovies.title = "Popular Movies"

for i in 0..<(popularMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (popularMovies.results?[i].poster_path)!!
let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (popularMovies.results?[i].backdrop_path)!!
popularMovies.results?[i].poster_path = tempPosterPath
popularMovies.results?[i].backdrop_path = tempBackDropPath
}
self.moviesCategories.append(popularMovies)
DispatchQueue.main.async {
self.tableView.reloadData()
}

} 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 {
var nowPlayingMovies = try
JSONDecoder().decode(MovieCategory.self, from: data)

for i in 0..<(nowPlayingMovies.results?.count ?? 0) {
let tempPosterPath = "https://image.tmdb.org/t/p/w500" + (nowPlayingMovies.results?[i].poster_path)!!
//let tempBackDropPath = "https://image.tmdb.org/t/p/w500" + (self.nowPlayingMovies.results?[i].backdrop_path)!!
nowPlayingMovies.results?[i].poster_path = tempPosterPath
}
self.moviesCategories.append(nowPlayingMovies)
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let jsonErr {
print("Error serializing json:", jsonErr)
}
}.resume()

}

}

表格 View 单元格

class HomeScreenCategoriesTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

@IBOutlet var collectionView: UICollectionView!
var sectionIndex:Int?
var movieCategory: MovieCategory!

override func awakeFromNib() {

super.awakeFromNib()
self.collectionView.delegate = self
self.collectionView.dataSource = self

DispatchQueue.main.async {
self.collectionView.reloadData()
}

}

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

if indexPath.row < movieCategory.results?.count ?? 0 {
let movie = movieCategory.results?[indexPath.row]
cell.test.text = movie.title
}

return cell
}

}

关于swift - 如何在子 UICollectionView 上获取 UITableView 的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57553545/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com