ios - 分组部分不显示在表格 View 中

标签 ios json swift uitableview

我的整个 TableView 都是以编程方式编写的,数据来自 JSON。我正在尝试按客户对单元格进行分组,代码似乎是正确的,但根本没有显示任何部分。

代码如下:

Portfolios.swift

import UIKit

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

PortfolioController.swift

import UIKit

class PortfolioController: UITableViewController {

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

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationController?.navigationBar.prefersLargeTitles = true
        view.backgroundColor = UIColor.blue
        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
                    let res = try JSONDecoder().decode([Portfolios].self, from: data)
                    self.portfoliosDic = Dictionary(grouping: res, by: { $0.customer})
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                    self.portfolios = try decoder.decode([Portfolios].self, from: data)

                    self.tableView.reloadData()

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

            }
        }.resume()
    }
    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]


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

        //cell.textLabel?.text = titleStr




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


        return cell
    }

}

更新:

因为它是一个 UIViewController Xcode 告诉我删除 override func

我添加了@IBOutlet weak var tableView: UITableView!

(由于某种原因,最终结果是一个空表)

使用 UITableViewController 代替:

import UIKit

class CustomerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!
    var sections = [Section]()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
        navigationController?.navigationBar.prefersLargeTitles = true
        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
                    let res = try decoder.decode([Portfolios].self, from: data)
                    let grouped = Dictionary(grouping: res, by: { $0.customer })
                    let keys = grouped.keys.sorted()
                    self.sections = keys.map({Section(name: $0, items: grouped[$0]!)})

                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                } catch {
                    print("Failed to decode json", error)
                }

            }
            }.resume()
    }
     func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }

     func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let section = sections[section]
        return section.items.count
    }

     func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section].name
    }

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
        let section = sections[indexPath.section]
        let item = section.items[indexPath.row]
        let titleStr = "\(item.serial) - \(item.manufacturer) - \(item.model)"
        cell.textLabel!.text = titleStr
        return cell
    }

}

最佳答案

首先为什么要对 JSON 进行两次解码?

由于未实现 titleForHeaderInSection 方法,因此未显示任何部分。

代码无论如何都不可靠,因为无法保证各部分的顺序。我建议为这些部分创建另一个结构。

struct Section {
    let name : String
    let items : [Portfolios]
}

struct Portfolios: Decodable {
    let customer, serial, rma, model: String
    let manufacturer: String
}

删除portfoliosportfoliosDic并声明数据源数组

var sections = [Section]()

对 JSON 进行分组、对键进行排序并将字典映射到 Section 实例

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let res = try decoder.decode([Portfolios].self, from: data)
    let grouped = Dictionary(grouping: res, by: { $0.customer })
    let keys = grouped.keys.sorted()
    self.sections = keys.map({Section(name: $0, items: grouped[$0]!)})

    DispatchQueue.main.async {
        self.tableView.reloadData()
    }
} catch {
    print("Failed to decode json", error)
}

TableView 数据源和委托(delegate)方法是

override func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let section = sections[section]
    return section.items.count
}

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sections[section].name
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
    let section = sections[indexPath.section]
    let item = section.items[indexPath.row]
    let titleStr = "\(item.serial) - \(item.manufacturer) - \(item.model)"
    cell.textLabel!.text = titleStr
    return cell
}

注意:

始终使 cellForRowAt 中的单元格出队

关于ios - 分组部分不显示在表格 View 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56169453/

相关文章:

ios - 自定义表格单元格类在 cellForRowAt 中不起作用

ios - Core Audio (iOS 5.1) Reverb2 属性不存在,错误代码-10877

ios - 创建一个透明的 UIView,其中包含一些信息

iphone - 有类似音量更改弹出窗口的 iOS UI 控件吗?

iphone - 在 iPhone 上将核心数据 NSManagedObject 转换为 JSON?

ios - 如何快速将枚举存储到可变数组中

ios - 在 UIStackView 上使用 UIImageView 自动布局 - iOS Swift

链接到网络服务的 Android native 应用程序,登录

javascript - 通过 javascript 触发数据工厂管道

ios - 类型 'UITableViewCell' 的值没有成员 'Job'