我已创建一个UITableView
,并希望将我的结果从api显示到UITableView
中的单元格。有一个带有标签出口的单元格类别,但该单元格中未显示任何内容。结果显示在控制台中,而不显示在单元格标签中
我尝试删除并添加新的约束。 我还添加了一个按钮来重新加载UITableView的内容,但是没有任何帮助。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
var result: String!
Alamofire.request(booksUrl, method: .get).responseJSON { (response) in
if response.result.isSuccess{
let bookJSON : JSON = JSON(response.result.value)
let tempResult = bookJSON["items"][0]["volumeInfo"]["title"].stringValue
result = tempResult
print(tempResult)
}
}
cell.bookNameLabel?.text = result
return cell
}
答案 0 :(得分:0)
请注意,Alamofire(和大多数网络请求)是异步的,这意味着在分派请求时,结果是未知的。
但是,tableview的数据源功能是一个同步方法,必须立即返回单元格。
最终结果是,当请求单元格时,结果是未知的,并且该单元格返回到要显示的表格视图中。一段时间后,收到了网络请求的结果,并打印在屏幕上,但是该单元永远不会更新。
要显示您的信息所需的最少更改为:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
Alamofire.request(booksUrl, method: .get).responseJSON { (response) in
if response.result.isSuccess{
let bookJSON : JSON = JSON(response.result.value)
let tempResult = bookJSON["items"][0]["volumeInfo"]["title"].stringValue
print(tempResult)
cell.bookNameLabel?.text = tempResult
}
}
return cell
}
此更新的代码的作用是使用Alamofire回调中的“单元”变量实例来更新单元标签。请注意,这并不是应该采取的方法,因为如果您开始拥有许多单元,其中的许多单元可能会被重用,并且最终您的数据将出现在整个位置并变得非常混乱。
您可能希望将网络请求移出该功能之外,并在自定义UITableViewCell中执行网络请求,请确保在单元被重用时取消网络请求,或者从视图控制器发出的viewDidLoad函数调度该请求完整/部分tableView.reloadData()。
鉴于您的API调用似乎是检索一本书的列表,并且每个单元格都显示一个书名,因此我建议执行一次请求,将所有书本结果存储到一个数组中,然后返回等于数组中的图书数量。
另一方面,您应努力将任何功能内执行的不同任务的数量保持在最低水平。因此,应该返回一个单元格的函数应该返回一个单元格,仅此而已……不执行网络请求。
推荐的代码结构将更接近此:
var books: JSON?
override func viewDidLoad() {
super.viewDidLoad()
retrieveListOfBooks()
}
func retrieveListOfBooks() {
Alamofire.request(booksUrl, method: .get).responseJSON { (response) in
DispatchQueue.main.async {
if response.result.isSuccess{
self.books = JSON(response.result.value)
self.tableView.reloadData()
}
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return books?["items"].count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! customCellTableViewCell
if indexPath.row < (books?["items"].count ?? 0) {
let book = books!["items"][indexPath.row]
let bookTitle = book["volumeInfo"]["title"].stringValue
cell.bookNameLabel?.text = bookTitle
}
return cell
}
警告:我尚未测试上面的代码,您可能还应该使用Codable来表示您的图书数据模型。