基本上不操纵视图(单元格)。使用数据模型。
struct Product {
let name : String
let value : String
let img : String
let id : Int
var selected = false
init(dict : [String:Any]) {
self.name = dict["name"] as? String ?? ""
self.value = dict["value"] as? String ?? ""
self.img = dict["img"] as? String ?? ""
self.id = dict["id"] as? Int ?? 0
}
}
And 永远不要使用多个数组作为数据源。这是一个非常不好的习惯。
将数据源数组声明为
var products = [Product]()
解析 JSON 数据并进行(更好的)错误处理
func downloadJsonWithURL() {
let url = URL(string: urlString)!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil { print(error!); return }
do {
if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [[String:Any]] {
self.products = jsonObj.map{ Product(dict: $0) }
DispatchQueue.main.async {
self.tableDetails.reloadData()
}
}
} catch {
print(error)
}
}
task.resume()
}
in cellForRow...
为标签分配名称并根据情况设置复选标记selected
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "filterSelectionCell", for: indexPath)
let product = products[indexPath.row]
cell.textLabel!.text = product.name
cell.accessoryType = product.selected ? .checkmark : .none
return cell
}
In didSelect...
toggle selected
并重新加载该行
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selected = products[indexPath.row].selected
products[indexPath.row].selected = !selected
tableView.reloadRows(at: [indexPath], with: .none)
}
获取所有选定的项目也非常容易。
let selectedItems = products.filter{ $0.selected }
或仅获取名称
let selectedNames = products.filter{ $0.selected }.map{ $0.name }
根本不需要从网站获取任何信息view. The 控制器始终从model并使用 tableview 数据源和委托来更新view.
如果你想将数据传递给另一个视图控制器传递Product
实例。它们包含所有相关信息。