以下是我的解析JSON并将其放入集合视图单元格的代码
import UIKit
let cellId = "cellId"
struct AnimeJsonStuff: Decodable {
let data: [AnimeDataArray]
}
struct AnimeLinks: Codable {
var selfStr : String?
private enum CodingKeys : String, CodingKey {
case selfStr = "self"
}
}
struct AnimeAttributes: Codable {
var createdAt : String?
var slug : String?
let synopsis: String?
private enum CodingKeys : String, CodingKey {
case createdAt = "createdAt"
case slug = "slug"
case synopsis = "synopsis"
}
}
struct AnimeRelationships: Codable {
var links : AnimeRelationshipsLinks?
private enum CodingKeys : String, CodingKey {
case links = "links"
}
}
struct AnimeRelationshipsLinks: Codable {
var selfStr : String?
var related : String?
private enum CodingKeys : String, CodingKey {
case selfStr = "self"
case related = "related"
}
}
struct AnimeDataArray: Codable {
let id: String?
let type: String?
let links: AnimeLinks?
let attributes: AnimeAttributes?
let relationships: [String: AnimeRelationships]?
private enum CodingKeys: String, CodingKey {
case id = "id"
case type = "type"
case links = "links"
case attributes = "attributes"
case relationships = "relationships"
}
}
class OsuHomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.title = "Kitsu - Your anime feed"
collectionView?.backgroundColor = UIColor(red:0.09, green:0.13, blue:0.19, alpha:1.0)
collectionView?.register(viewControllerCells.self, forCellWithReuseIdentifier: cellId)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 350, height: 150)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 15, left: 0, bottom: 10, right: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
class viewControllerCells: UICollectionViewCell {
func jsonDecoding() {
let jsonUrlString = "https://kitsu.io/api/edge/anime"
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 animeJsonStuff = try JSONDecoder().decode(AnimeJsonStuff.self, from: data)
for anime in animeJsonStuff.data {
// print(anime.id)
// print(anime.type)
// print(anime.links?.selfStr)
let animeName = anime.attributes?.slug
let animeSynopsis = anime.attributes?.synopsis
print(animeName)
DispatchQueue.main.async {
self.nameLabel.text = animeName
self.synopsis.text = animeSynopsis
}
for (key, value) in anime.relationships! {
// print(key)
// print(value.links?.selfStr)
// print(value.links?.related)
}
}
} catch let jsonErr {
print("Error serializing json", jsonErr)
}
}.resume()
}
let nameLabel: UILabel = {
let label = UILabel()
label.textColor = UIColor.black
return label
}()
let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
let synopsis: UILabel = {
let label = UILabel()
label.textColor = UIColor.black
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
jsonDecoding()
self.layer.shadowOpacity = 0.05
self.layer.shadowRadius = 0.05
self.layer.cornerRadius = 1
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
backgroundColor = UIColor(red:0.86, green:0.87, blue:0.89, alpha:1.0)
addSubview(nameLabel.self)
addSubview(synopsis.self)
addConstraintsWithFormat("H:|-18-[v0]|", views: synopsis)
addConstraintsWithFormat("V:|-8-[v0]|", views: synopsis)
addConstraintsWithFormat("H:|-12-[v0]|", views: nameLabel)
}
}
extension UIColor {
static func rgb(_ red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor {
return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: 1)
}
}
extension UIView {
func addConstraintsWithFormat(_ format: String, views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerated() {
let key = "v\(index)"
viewsDictionary[key] = view
view.translatesAutoresizingMaskIntoConstraints = false
}
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
但有效但不是像这样输入所有数据
Optional("cowboy-bebop")
Optional("cowboy-bebop-tengoku-no-tobira")
Optional("trigun")
Optional("witch-hunter-robin")
Optional("beet-the-vandel-buster")
Optional("eyeshield-21")
Optional("honey-and-clover")
Optional("hungry-heart-wild-striker")
Optional("initial-d-fourth-stage")
Optional("monster")
Optional("cowboy-bebop")
Optional("cowboy-bebop-tengoku-no-tobira")
Optional("trigun")
Optional("witch-hunter-robin")
Optional("beet-the-vandel-buster")
Optional("eyeshield-21")
Optional("honey-and-clover")
Optional("hungry-heart-wild-striker")
Optional("initial-d-fourth-stage")
Optional("monster")
Optional("cowboy-bebop")
Optional("cowboy-bebop-tengoku-no-tobira")
Optional("trigun")
Optional("witch-hunter-robin")
Optional("beet-the-vandel-buster")
Optional("eyeshield-21")
Optional("honey-and-clover")
Optional("hungry-heart-wild-striker")
Optional("initial-d-fourth-stage")
Optional("monster")
它就像this那样错了它应该从上到下显示每个节目而不仅仅是最后一个节目。之前我确实问过这个问题并且他们说把它放在主视图中然后加载然后返回索引路径上的项目的单元格,我猜想anime.attrubites.slug似乎没有工作。
答案 0 :(得分:0)
请检查:
OsuHomeController
let cellId = "cellId"
struct AnimeJsonStuff: Decodable {
let data: [AnimeDataArray]
}
struct AnimeLinks: Codable {
var selfStr : String?
private enum CodingKeys : String, CodingKey {
case selfStr = "self"
}
}
struct AnimeAttributes: Codable {
var createdAt : String?
var slug : String?
let synopsis: String?
private enum CodingKeys : String, CodingKey {
case createdAt = "createdAt"
case slug = "slug"
case synopsis = "synopsis"
}
}
struct AnimeRelationships: Codable {
var links : AnimeRelationshipsLinks?
private enum CodingKeys : String, CodingKey {
case links = "links"
}
}
struct AnimeRelationshipsLinks: Codable {
var selfStr : String?
var related : String?
private enum CodingKeys : String, CodingKey {
case selfStr = "self"
case related = "related"
}
}
struct AnimeDataArray: Codable {
let id: String?
let type: String?
let links: AnimeLinks?
let attributes: AnimeAttributes?
let relationships: [String: AnimeRelationships]?
private enum CodingKeys: String, CodingKey {
case id = "id"
case type = "type"
case links = "links"
case attributes = "attributes"
case relationships = "relationships"
}
}
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var isDataLoaded = false
var animeNames: [String] = []
var animeSynopsis: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.jsonDecoding()
// Do any additional setup after loading the view, typically from a nib.
navigationItem.title = "Kitsu - Your anime feed"
collectionView?.backgroundColor = UIColor(red:0.09, green:0.13, blue:0.19, alpha:1.0)
collectionView?.register(viewControllerCells.self, forCellWithReuseIdentifier: cellId)
collectionView?.delegate = self
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return animeNames.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! viewControllerCells
cell.nameLabel.text = animeNames[indexPath.row]
cell.synopsis.text = animeSynopsis[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 350, height: 150)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 15, left: 0, bottom: 10, right: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func jsonDecoding() {
let jsonUrlString = "https://kitsu.io/api/edge/anime"
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 animeJsonStuff = try JSONDecoder().decode(AnimeJsonStuff.self, from: data)
for anime in animeJsonStuff.data {
// print(anime.id)
// print(anime.type)
// print(anime.links?.selfStr)
if let animeName = anime.attributes?.slug {
self.animeNames.append(animeName)
} else {
self.animeNames.append("-")
}
if let animeSynop = anime.attributes?.synopsis {
self.animeSynopsis.append(animeSynop)
} else {
self.animeSynopsis.append("-")
}
for (key, value) in anime.relationships! {
// print(key)
// print(value.links?.selfStr)
// print(value.links?.related)
}
}
self.isDataLoaded = true
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
} catch let jsonErr {
print("Error serializing json", jsonErr)
}
}.resume()
}
}
viewControllerCells
class viewControllerCells: UICollectionViewCell {
let nameLabel: UILabel = {
let label = UILabel()
label.textColor = UIColor.black
return label
}()
let profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFit
return imageView
}()
let synopsis: UILabel = {
let label = UILabel()
label.textColor = UIColor.black
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
self.layer.shadowOpacity = 0.05
self.layer.shadowRadius = 0.05
self.layer.cornerRadius = 1
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
backgroundColor = UIColor(red:0.86, green:0.87, blue:0.89, alpha:1.0)
addSubview(nameLabel.self)
addSubview(synopsis.self)
addConstraintsWithFormat("H:|-18-[v0]|", views: synopsis)
addConstraintsWithFormat("V:|-8-[v0]|", views: synopsis)
addConstraintsWithFormat("H:|-12-[v0]|", views: nameLabel)
}
}
extension UIColor {
static func rgb(_ red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor {
return UIColor(red: red/255, green: green/255, blue: blue/255, alpha: 1)
}
}
extension UIView {
func addConstraintsWithFormat(_ format: String, views: UIView...) {
var viewsDictionary = [String: UIView]()
for (index, view) in views.enumerated() {
let key = "v\(index)"
viewsDictionary[key] = view
view.translatesAutoresizingMaskIntoConstraints = false
}
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
}