从 JSON 数据向 tableview 添加部分的问题

Posted

技术标签:

【中文标题】从 JSON 数据向 tableview 添加部分的问题【英文标题】:Issue adding sections to tableview from JSON data 【发布时间】:2019-05-15 20:57:45 【问题描述】:

我正在尝试对从 JSON 数据填充的表格视图进行分组。

下面是一个例子:

  ["customer":"Customer1","serial":"34543453",
"rma":"P2384787","model":"M282","manufacturer":"Manufacturer1",

 "customer":"Customer1","serial":"13213214",
"rma":"P2384787","model":"M384","manufacturer":" Manufacturer1",

"customer":"Customer2","serial":"1212121323",
"rma":"P3324787","model":"M384","manufacturer":" Manufacturer1"]

我想根据客户名称对表格视图进行分组。 所以在我的情况下,它应该看起来像:

客户1

34543453 - 制造商1 - M282

13213214 - 制造商1 - M384

客户2

1212121323 - 制造商1 - M384

注意:

之所以有一条线分隔系列制造商和型号是因为 CustomerViewController.swift 中的这个分隔符:

let titleStr = [item.serial, item.manufacturer, item.model].compactMap  $0 .joined(separator: " - ")

PortfolioController.swift

import UIKit

class PortfolioController: UITableViewController 

    var portfolios = [Portfolios]()

    override func viewDidLoad() 
        super.viewDidLoad()
        navigationController?.navigationBar.prefersLargeTitles = true
        navigationItem.title = "Customer"
        fetchJSON()
    

     func fetchJSON()
        let urlString = "https://www.example.com/example/example.php"
        guard let url = URL(string: urlString) else  return 
        URLSession.shared.dataTask(with: url)  (data, _, error) in
            DispatchQueue.main.async 
                if let error = error 
                    print("Failed to fetch data from url", error)
                    return
                
                guard let data = data else  return 
                do 

                    let decoder = JSONDecoder()

                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    self.portfolios = try decoder.decode([Portfolios].self, from: data)

                    self.tableView.reloadData()

                 catch let jsonError 
                    print("Failed to decode json", jsonError)
                

            
        .resume()
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

        return portfolios.count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
        let customer = portfolios[indexPath.row]
        //cell.textLabel?.text = customer.serial


        let titleStr = [customer.serial, customer.manufacturer, customer.model].compactMap  $0 .joined(separator: " - ")


        print(titleStr)
        // Get references to labels of cell
        cell.textLabel!.text = titleStr


        return cell
    




Portfolios.swift

import UIKit

    struct Portfolios: Codable 
        let customer, serial, rma, model: String
        let manufacturer: String
    

【问题讨论】:

这是我之前回答的***.com/questions/56154652/… 的唯一方法 我已经简化了一切,现在正在使用您推荐的结构 但是我在哪里放:let res = try! JSONDecoder().decode([Root].self,from:data) let dic = Dictionary(grouping: res, by: $0.customer) // [String:[Root]] 使用我上面的这个新代码 @Sh_Khan 你在吗? 【参考方案1】:

1- 创建实例变量

var portfoliosDic = [String:[Portfolios]]()

2- 在这里赋值

let res = try JSONDecoder().decode([Portfolios].self, from: data)
self.portfoliosDic = Dictionary(grouping: res, by:  $0.customer)
DispatchQueue.main.async 
 self.tableView.reloadData()


  override func numberOfSections(in tableView: UITableView) -> Int 
    return portfoliosDic.keys.count
  

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

       let keys = Array(portfoliosDic.keys) 
       let item = portfoliosDic[keys[section]]! 
        return item.count
    

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
           let keys = Array(portfoliosDic.keys) 
           let arr = portfoliosDic[keys[indexPath.section]]! 
           let customer = arr[indexPath.row]

        //cell.textLabel?.text = customer.serial


        let titleStr = [customer.serial, customer.manufacturer, customer.model].compactMap  $0 .joined(separator: " - ")


        print(titleStr)
        // Get references to labels of cell
        cell.textLabel!.text = titleStr


        return cell
    

【讨论】:

不,它必须在当前位置,并且还添加了答案中的编辑,替换表数据源和委托 section 也必须在cellForRowAt 中定义,对吗?因为它给了我一个错误,说未解析的标识符 我已经实现了一切,构建后没有视觉差异。没有任何内容被分组,没有任何部分。还有什么我必须启用的吗??

以上是关于从 JSON 数据向 tableview 添加部分的问题的主要内容,如果未能解决你的问题,请参考以下文章

向tableview添加行以添加行和核心数据

如何从 TableModel 向 qml TableView 添加标题

从 Tableview 的第 0 部分中删除按钮

从 JSON 解析数据直接到 UITableView

带有部分模板的 TableView

问:带有 JSON 文件的 SearchBar Tableview