【问题标题】:Data is not loaded on the second viewcontroller from JSON数据未从 JSON 加载到第二个视图控制器上
【发布时间】:2020-07-25 01:35:50
【问题描述】:

我终于能够将数据从 API 加载到 tableview 中。当我切换到一个角色时,我想在下一个视图控制器中获取关于他的数据。但是当我切换到下一个 VC 时,我没有收到任何错误,但我的数据为零。请帮助我并告诉我我做错了什么以及我的错误在哪里?

我有 Data.swift

struct PagedCharacters: Decodable {
    let info: Info
    let results: [Results]

}
struct Info: Decodable {
    let count: Int
    let pages: Int
    let next: String
    let prev: String
}

struct Results: Decodable {
    let id: Int
    let name: String
    let status: String
    let species: String
    let image: String
    let url: String
    let type: String
}

我的主要 VC: Viewcontroller.swift

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

      @IBOutlet weak var uiTableView: UITableView!
       var characters:[Results]?
           var nextPageUrl:String!

           override func viewDidLoad() {
               super.viewDidLoad()
               getIntitalRickAndMortyData()


               self.uiTableView.dataSource = self
               self.uiTableView.delegate = self

               // Do any additional setup after loading the view.
           }






           func getIntitalRickAndMortyData(){
               characters = []
               //here first page is next page
               nextPageUrl = "https://rickandmortyapi.com/api/character/"
               getRickAndMortyData()
           }

           func getRickAndMortyData() {

               //construct the url, use guard to avoid nonoptional
               guard let urlObj = URL(string: nextPageUrl) else
               { return }

               //fetch data
               URLSession.shared.dataTask(with: urlObj) {[weak self](data, response, error) in

                   //to avoid non optional in JSONDecoder
                   guard let data = data else { return }

                   do {
                       //decode object
                       let downloadedRickAndMorty = try JSONDecoder().decode(PagedCharacters.self, from: data)
                       self?.characters?.append(contentsOf: downloadedRickAndMorty.results)
                       self?.nextPageUrl = downloadedRickAndMorty.info.next

                       DispatchQueue.main.async {
                           self?.uiTableView.reloadData()
                       }
                       print(self?.characters as Any)

                   } catch {
                       print(error)

                   }

                   }.resume()

           }


           func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
               return self.characters?.count ?? 0
           }

           func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



               if let count = characters?.count, count>1{
                   let lastElement = count - 1
                   if indexPath.row == lastElement {
                       //call get api for next page
                       getRickAndMortyData()

                   }
               }


              let cell = tableView.dequeueReusableCell(withIdentifier: "characterCell", for: indexPath)


             cell.textLabel?.text = "Name: " + (self.characters?[indexPath.row].name ?? "default")

               return cell
           }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let character = characters?[indexPath.row]
           performSegue(withIdentifier: "toCharacterDetailVC", sender: self)
        print(character?.name)
       }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

       if segue.identifier == "toCharacterDetailVC" {
           if let destVC = segue.destination as? CharacterDetailViewController {
              destVC.character = sender as? Results

       }
    }



       }
}

第二个VC CharacterDetailViewController

import UIKit


class CharacterDetailViewController: UIViewController {


    @IBOutlet var statusLabel: UILabel!
    @IBOutlet var speciesLabel: UILabel!
    @IBOutlet var typeLabel: UILabel!

public var character: Results?


    override func viewDidLoad() {

       title = character?.name
              statusLabel.text = character?.status
              speciesLabel.text = character?.species
              typeLabel.text = character?.type == "" ? "Not Available" : character?.type
              print(character?.name)
        super.viewDidLoad()



}
}

【问题讨论】:

    标签: ios json swift uitableview uiviewcontroller


    【解决方案1】:
    var character: Results? {
        didSet {
            title = character?.name
            statusLabel.text = character?.status
            speciesLabel.text = character?.species
            typeLabel.text = character?.type == "" ? "Not Available" : character?.type
        }
    }
    

    【讨论】:

    • 伙计们,这对我没有帮助,没有任何改变.. :(
    • 您是否删除了 viewDidLoad 中的所有内容?
    【解决方案2】:

    您似乎没有在第二个视图控制器中分配角色。首先将其公开。

    public var character: Results?
    

    然后在调用第二个视图控制器之前根据用户选择分配字符。

     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
           let character = characters[indexPath.row]
            self.performSegue(withIdentifier: "toCharacterDetailVC ", sender: testArray)
        }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
       if segue.identifier == "toCharacterDetailVC" {
           if let destVC = segue.destination as? CharacterDetailViewController {
              destVC.character = sender as! Results 
    
       }
    }
    

    【讨论】:

    • @Dilan Anuruddha 我复制了这段代码,但对我没有帮助。我无法解决问题
    • 你能在'didSelectRowAt'中添加打印语句并检查字符数据吗?
    • 参见 'print(character.name)' -- 'Rick Sanchez',但如果我使用 destVC.character = sender as? Results 如果我使用“!”,“我”已经崩溃“无法转换类型的值" , 对不起我的英语不好
    • 请用最新的修改更新问题代码
    • 在赋值之前调用 super.viewDidLoad()。我的意思是在 CharacterDetailViewController 中的此行之后添加其他行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 2023-03-20
    • 1970-01-01
    • 2016-09-25
    • 2013-05-10
    • 1970-01-01
    相关资源
    最近更新 更多