我获取了一个JSON文件(作为API(。数据是NFT,我想在我的ViewController中显示NFT的值。我已经制作了一个表视图,它可以生成自定义单元格并列出NFT,但现在我想通过在tableView的单元格中添加集合视图来进一步自定义我的项目。在这个收藏视图中,我想把NFT的创造者放在首位。我之所以堆叠,是因为在我看来,我已经完成了正确的过程,但最终这些事情没有出现在我的屏幕上。
我会把我写的代码给你,看看是否有人能帮我;第一单元格";我想要一个集合视图,在这个视图下我想要一份我的NFT列表(由AssetTableViewCell上的自定义单元格创建的列表(。
视图控制器:
import UIKit
class LobbyViewController: UIViewController {
// MARK: - IBProperties
@IBOutlet weak var tableView: UITableView!
// MARK: - Properties
var data: [DataEnum] = []
var likes:[Int] = []
var numlikes: Int = 0
var nfts: [Nft] = []
var creators : [Creator] = []
var users: [User] = []
var icons: [Icon] = []
var loadData = APICaller()
// MARK: - Life Cyrcle
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(AssetTableViewCell.nib(), forCellReuseIdentifier: "AssetTableViewCell")
tableView.register(CreatorsTableViewCell.nib(), forCellReuseIdentifier: "CreatorsTableViewCell")
tableView.dataSource = self //method to generate cells,header and footer before they are displaying
tableView.delegate = self //method to provide information about these cells, header and footer ....
downloadJSON {
self.tableView.reloadData()
print("success")
}
loadData.downloadData { (result) in
// print(result)
print("success")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? NftListViewController {
destination.nft = nfts[tableView.indexPathForSelectedRow!.row]
destination.delegate = self
}
}
// MARK: - Methods
func downloadJSON(completed: @escaping () -> ()) {
let url = URL(string: "https://public.arx.net/~chris2/nfts.json")
URLSession.shared.dataTask(with: url!) { data, response, error in
if error == nil {
do {
self.nfts = try JSONDecoder().decode([Nft].self, from: data!)
self.creators = try JSONDecoder().decode([Creator].self, from: data!)
self.creators.forEach{ creator in
self.data.append(.type1(creators: creator))
}
self.nfts.forEach { nft in
self.data.append(.type2(nft: nft))
}
print(self.nfts)
DispatchQueue.main.async {
completed()
}
}
catch {
print("error fetching data from api")
}
}
}.resume()
}
}
// MARK: - Extensions
extension LobbyViewController : UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 20.0
}
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
//orizo ton arithmo ton rows tou table
func tableView(_ tableView: UITableView, numberOfRowsInSection section : Int) ->Int {
return data.count
}
//gemizo ta rows tou table
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch self.data[indexPath.item] {
case .type1(let creator):
let cell = tableView.dequeueReusableCell(withIdentifier: "CreatorsTableViewCell",
for: indexPath) as! CreatorsTableViewCell
let creator = creators[indexPath.row]
cell.creatorNames?.text = creator.user.username
let crImg = (creator.profileImgURL)
//print(crImg)
cell.creImg.download(from: crImg)
return UITableViewCell()
case .type2(let nft):
let cell = tableView.dequeueReusableCell(withIdentifier: "AssetTableViewCell",
for: indexPath) as! AssetTableViewCell
let nft = nfts[indexPath.row]
cell.nameLabel?.text = nft.name
cell.nameLabel.layer.cornerRadius = cell.nameLabel.frame.height/2
cell.likesLabel?.text = "((numlikes))"
let imgUrl = (nft.image_url)
print(imgUrl)
cell.iconView.download(from: imgUrl)
cell.iconView.layer.cornerRadius = cell.iconView.frame.height/2
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetails", sender: self)
}
}
extension LobbyViewController : TestDelegate{
func sendBackTheLikess(int: Int) {
numlikes = int
tableView.reloadData()
}
}
extension UIImageView {
func download(from url: URL, contentMode mode: ContentMode = .scaleAspectFit) {
contentMode = mode URLSession.shared.dataTask(with: url) { data, response, error in
guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, let mimeType = response?.mimeType, mimeType.hasPrefix("image"), let data = data, error == nil, let image = UIImage(data: data) else { return }
DispatchQueue.main.async() { [weak self] in
self?.image = image
}
}.resume()
}
func download(from link: String, contentMode mode: ContentMode = .scaleAspectFit) {
guard let url = URL(string: link) else { return }
downloaded(from: url, contentMode: mode)
}
}
}
// MARK: - Enums
enum DataEnum { case type1(creators: Creator) case type2(nft: Nft) }
// MARK: - Struct
struct Constants { static let url = "https://public.arx.net/~chris2/nfts.json" }
CreatorTableViewCell
import UIKit
class CreatorsTableViewCell: UITableViewCell {
//MARK: -- IBProperties
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var creatorNames: UILabel!
@IBOutlet var creImg: UIImageView!
//MARK: -- Properties
var creators : Creator?
var users : User?
static let identifier = "CreatorsTableViewCell"
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
//MARK: -- Functions
static func nib() -> UINib{ return UINib(nibName: "CreatorsTableViewCell", bundle: nil)
}
}
// MARK: - Extensions
extension UIImageView { func downloadImgs(from url: URL, contentMode mode: ContentMode = .scaleAspectFit) { contentMode = mode URLSession.shared.dataTask(with: url) { data, response, error in guard let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, let mimeType = response?.mimeType, mimeType.hasPrefix("image"), let data = data, error == nil, let image = UIImage(data: data) else { return } DispatchQueue.main.async() { [weak self] in self?.image = image } }.resume() } func downloadImgs(from link: String, contentMode mode: ContentMode = .scaleAspectFit) { guard let url = URL(string: link) else { return } downloaded(from: url, contentMode: mode) } }
AssetTableViewCell
import UIKit
class AssetTableViewCell: UITableViewCell {
//MARK: -- IBProperties
@IBOutlet var nameLabel : UILabel!
@IBOutlet var iconView : UIImageView!
@IBOutlet var likesLabel: UILabel!
//MARK: -- Properties
var nfts:Nft?
static let identifier = "AssetTableViewCell"
//MARK: -- Life Cyrcle
override func awakeFromNib() {
super.awakeFromNib()
nameLabel.layer.cornerRadius = nameLabel.frame.height/2
likesLabel.layer.cornerRadius = likesLabel.frame.height/2
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
//MARK: -- Functions
static func nib() -> UINib{
return UINib(nibName: "AssetTableViewCell", bundle: nil)
}
}
型号
import Foundation
// MARK: - Nft struct Nft: Codable{ let id:Int let image_url:String let name:String let creator: Creator }
// MARK: - Icon struct Icon:Codable{ let image_url:String }
// MARK: - Creator struct Creator: Codable { let user: User let profileImgURL: String
enum CodingKeys: String, CodingKey {
case user
case profileImgURL = "profile_img_url"
}
}
// MARK: - User struct User: Codable { let username: String? }
APICaller
//
// APICaller.swift
// Nft Assets
//
// Created by Ben Seferidis on 11/10/22
import Foundation
final class APICaller {
static let shared = APICaller()
public struct Constants {
static let url = "https://public.arx.net/~chris2/nfts.json"
}
public func downloadData(completion:@escaping (Result<[Nft], Error>) -> Void )
{
guard let url = URL(string:Constants.url)else{
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
//print(response)
print("here")
guard let data = data , error == nil else{
print("something went wrong")
return
}
print("here4")
//mexri edo exoume parei ta data kai tora me to do-catch tha ta kanoume convert se object
do{
//Decode the response
let nfts = try JSONDecoder().decode([Nft].self, from: data)
completion(.success(nfts))
print(nfts)
}catch{
completion(.failure(error))
}
}
task.resume()
}
}
您可以在CreatorsTableViewCell中实现CollectionView数据源和Delegate代码。此外,如果要处理TableView,请尝试将indexPath.item
更改为indexPath.row
。