iOS UITableView 未显示

iOS UITableView Not Showing

我是 iOS 的新手,正在从 GitHub API 进行网络抓取,但无法在 table 视图中显示用户。下面是代码,

视图控制器:

    import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var avatarImage: UIImageView!
    @IBOutlet weak var userName: UILabel!
    @IBOutlet weak var usersTableView: UITableView!

    var network = Network()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        network.delegate = self
        usersTableView.dataSource = self
    }

    override func viewWillAppear(_ animated: Bool) {
        network.network()
    }
}

extension ViewController: NetworkDelegate {
    func updateTableView() {
        DispatchQueue.main.async {
            self.usersTableView.reloadData()
        }
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let users = network.users {
            print(users.count)
            return users.count
        } else {
            return 0
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print("CALLED")
        let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath) as! UserViewCell
        return cell
    }
}

btw,标识符来自.xib文件,标识符匹配,我认为问题不在这里。

网络文件

import Foundation

protocol NetworkDelegate {
    func updateTableView()
}

class Network {
    var users: [GitHub]?
    var delegate: NetworkDelegate?

    func network() {
        let url = "https://api.github.com/users"
        let request: URLRequest?

        if let URL = URL(string: url) {
            request = URLRequest(url: URL)
            URLSession.shared.dataTask(with: request!) { result, response, error in
                if let data = result {
    //                print(String(data: data, encoding: .utf8)!)

                    self.users = self.parseJSON(data)
                    self.delegate?.updateTableView()
                } else {
                    print(error!.localizedDescription)
                }
            }
            .resume()
        }
    }

    private func parseJSON(_ data: Data) -> [GitHub]? {
        let json = JSONDecoder()
        do {
            let decodedData = try json.decode([GitHub].self, from: data)
//            print(decodedData)
            return decodedData
        } catch {
            print(error.localizedDescription)
        }
        return nil
    }
}

GitHubAPI模型

struct GitHub: Codable {
    let login: String
    let id: Int
    let node_id: String
    let avatar_url: String
    let gravatar_id: String
    let url: String
    let html_url: String
    let followers_url: String
    let following_url: String
    let gists_url: String
    let starred_url: String
    let subscriptions_url: String
    let organizations_url: String
    let repos_url: String
    let events_url: String
    let received_events_url: String
    let type: String
    let site_admin: Bool
}

当我在模拟器上运行这段代码时,输​​出为空白(标签下方)

无法找出我哪里做错了

提前致谢。

尝试在不使用委托模式的情况下使用完成处理程序重构您的代码。

在你的 network file:

enum ApiError: Error {
    case network(Error)
    case genericError
    case httpResponseError
    case invalidData
    case decoding
    // you can handle your specific case 
}


  func network(completion: @escaping ( _ error: ApiError?, _ users: [GitHub]?)-> Void) {
        let url = "https://api.github.com/users"
        let request: URLRequest?
        
        if let URL = URL(string: url) {
            request = URLRequest(url: URL)
            URLSession.shared.dataTask(with: request!) { result, response, error in
                if let error = error {
                    completion(.network(error), nil)
                    return
                }
                guard let httpResponse = response as? HTTPURLResponse,
                      (200...299).contains(httpResponse.statusCode) else {
                          completion( .httpResponseError, nil)
                          return
                      }
                guard let data = result else {
                    completion(.invalidData, nil)
                    return
                }
                do {
                    let decodedData = try JSONDecoder().decode([GitHub].self, from: data)
                    completion(nil, decodedData)
                } catch {
                    completion(.decoding, nil)
                }
            }
            .resume()
        }
    }

然后在你的 ViewController 中你可以这样使用它:

   override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        network.network { [weak self] error, users in
            guard let self = self else { return }
            if let error = error {
                print(error)
                return
            }
            DispatchQueue.main.async {
                guard let users = users else { return }
                self.users = users
                self.tableView.reloadData()
            }
        }
    }

如果它仍然没有显示并且 cellForRow 没有被调用,则您的约束可能有问题并且 tableView 框架为零(高度、宽度或两者都有).

尝试调试 numberOfRowsInSection 内的断点,然后在您的调试区域 po tableView 或仅打印 tableView 并检查宽度或高度是否为零。它可能会被调用几次。第一次框架应该为零,但在某些时候你应该得到一个具有高度和宽度的框架。如果不这样做,请检查您的约束条件。

您可以查看我的示例,其中有一个 table 视图 375 x 641

如果您的单元格是一个 xib 文件,那么您必须使用 tableView 注册您的单元格。

viewDidLoad

中调用数据源之前
override func viewDidLoad() {
    super.viewDidLoad()
        // Do any additional setup after loading the view.
    usersTableView(UINib(nibName: "userCell", bundle: nil), forCellReuseIdentifier: "userCell")
    network.delegate = self
    usersTableView.dataSource = self
    }