首页 > 解决方案 > Swift - 按日期对表格视图数据进行排序,仅对初始视图中的单元格进行排序

问题描述

我有一个 UITableView,其中添加了 100 个数据元素。数据是通过以下方法生成的:

    func generateMockAPIResponse(generate numberRecordsToGenerate: Int) -> [CellData] {
        
        var data: [CellData] = []
        let type = ["PreCount", "PostCount"]
        let location = ["BBS", "LHR", "CDG", "CCF"]
        
        for _ in 1...numberRecordsToGenerate {
            let date = Date().changed(day: -Int.random(in: 0...60)) ?? Date()
            let preTotal = Double.random(in: 500..<1000)
            let postTotal = Double.random(in: 10000..<50000)
            let difference = postTotal - preTotal
            data.append(
                CellData(
                    type: type[Int.random(in: 0..<type.count)],
                    date: date,
                    id: "AG\(String(Int.random(in: 100..<900)))",
                    preTotal: preFuel,
                    postTotal: postFuel,
                    difference: uplift,
                    dur: Double.random(in: 0.80...0.85),
                    location: location[Int.random(in: 0..<location.count)]))
        }
        return data
    }

本质上,我在这里生成了一个模拟 API 响应。我在 viewDidLoad 中调用了这个方法:

var data = [CellData]()

override func viewDidLoad() {
    super.viewDidLoad()
    
    // To be removed once API is in place
    data = sortAndConvertData(data: generateMockAPIResponse(generate: 100))            
}

然后我有一个 sortAndConvert 函数:

    private func sortAndConvertData(data: [CellData]) -> [CellData] {
        var convertedData: [CellData] = []
        
        for data in data {
            if let preTotal = data.preTotal,
                let postTotal = data.postTotal,
                let difference = data.difference,
                let dur = data.dur,
                
                let convertedPreTotal = // code converts to difference unit of measure,
                let convertedPostTotal = // code converts to difference unit of measure,
                let convertedDifference = // code converts to difference unit of measure,
                let convertedDur = // code converts to difference unit of measure
            {
                
                convertedData.append(
                    CellData(
                        type: data.type,
                        date: data.date,
                        id: data.flightNumber,
                        preTotal: convertedPreFuel,
                        postTotal: convertedPostFuel,
                        difference: convertedUplift,
                        dur: convertedDensity,
                        location: data.location
                    )
                )
            }
        }
        return convertedData.sorted(by: { $0.date?.compare($1.date ?? Date()) == .orderedDescending })
    }
}

所以我最终得到的数据应该按日期排序。然后我声明我的单元格如下:

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell: HistoryTableViewCell = tableView.dequeue(indexPath: indexPath)
        cell.data = data[indexPath.row]

        cell.backgroundColor = indexPath.row % 2 == 0 ? UIColor.i6.alternateTableCells : .white
        
        return cell
    }

所以这一切都适用于表格视图中的所有单元格。但是,当用户滚动时,由于出队过程,订单会变得混乱。如何避免订单被可重复使用的单元格破坏?

编辑:

在自定义单元格中设置数据:

   private func populateData() {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd-MMM-yy"
        
        if let dataDate = data?.date,
            let dataPreTotal = data?.preFuel,
            let dataPostTotal = data?.postFuel,
            let dataDifference = data?.uplift,
            let dataDur = data?.density
        {
            typeLabel.text = data?.type
            date.valueLabel.text = formatter.string(from:dataDate)
            id.valueLabel.text = data?.id
            preTotal.valueLabel.text = String(format: "%.0f", dataPrefuel)
            postTotal.valueLabel.text = String(format: "%.0f", dataPostFuel)
            difference.valueLabel.text = String(format: "%.0f", dataUplift)
            dur.valueLabel.text = String(format: "%.2f", dataDensity)
            location.valueLabel.text = data?.location
        }
    }

这被称为:

override func didMoveToSuperview() {
    populateData()
    configureAutoLayout()
}

标签: swiftxcodeuitableviewcustom-cell

解决方案


最后我设法解决了这个问题。问题是我使用 didMoveToSuperView() 在自定义单元类中调用 populateData() 方法

我现在已将其设置为自定义单元类中数据对象的 didSet() 方法:

    var data: FuelHistoryTableViewController.CellData? {
    didSet {
        populateData()
    }
}

推荐阅读