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