如何使用带有urlsession的函数更新TableViewCell? Swift
我有一个函数可以获取位置坐标并获取天气数据。该功能在代码的其他地方使用。如何使用带有urlsession的函数更新TableViewCell? Swift
目前我在cellForRowAt中直接使用了urlsession,但不想重复代码。有没有办法在TableViewController的cellForRowAt中调用这个天气函数来更新单元格?
class Data {
static func weather (_ coord:String, completion: @escaping...([String?]) ->(){
let url = URL(string: "https://")
let task = URLSession.shared.dataTask(with: url!) { data, response, error in
let json = processData(data) //returns [String]?
completion(json)
}
task.resume()
}
static func processData(_ data: Data) -> [String]? {
}
}
在cellForRowAt,如何修改天气函数返回的细胞之前在这里得到的值,但天气功能的原始功能以完成也应该留下来吗?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ...
Data.weather() ** ??? **
cell.label.text = "" // value from weather
return cell
}
触发cellForRowAt indexPath
网络呼叫是一个坏主意。只要用户滚动浏览表格视图,就会调用该方法。这可能会导致很多网络电话。
相反,你应该:
- 让需要只有当网络呼叫。例如,你可以在
viewWillAppear
。每当应用切换到您的桌面时,都会调用此方法。 -
存储网络调用的结果在模型中。这可能与
array
一样简单。 - 重新绘制tableView与
reloadData
- 在
cellForRowAt indexPath
配置单元的数据从array
。
让我们看一个例子(它是不完整的,但应该给你一个想法,做什么):
class WeatherTableView: UITableView {
var weatherData: [String]
override func viewWillAppear(_ animated: Bool) {
loadWeatherData()
}
private func loadWeatherData() {
// I just set some data here directly. Replace this with your network call
weatherData = ["Here comes the sun", "Rainy with chance of meatballs", "It's raining cats and dogs"]
// Make sure the tableView is redrawn
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "weatherDataCell")
cell.label.text = weatherData[indexPath.row]
return cell
}
}
感谢您的解释。问题的一部分不会保持不变 - 在viewWill中通过for-in循环收集值时也会出现一个带有异步调用的函数? –
我不确定,如果我正确理解你的问题。在viewWillAppear中进行网络调用可确保只有在屏幕上显示视图时才进行网络调用。一旦绘制完成,'viewWillAppear'不会再次加载。你可以使用断点来检查它。 –
另外,如果您发现我的答案有帮助,请将其作为接受的答案:) –
不更新** **观点在**查看* *。更新**控制器**中的**模型**,然后更新**视图**。 – vadian
tableView.reloadData()完成后使用它(当你的请求完全调用时) –