陳香君
陳香君

Reputation: 39

How to fix 'data of UITableViewCell exchange'?

My certain two rows of data of UITableViewCell exchange, and this is how it looks. The row data after exchanged are the right, and they're wrong before exchanged.

And I'm sorry for not have enough reputation to post .gif image.

Is there any way to avoid the data exchange to the wrong row?

The links of problems above seem to be related to mine, but I think my problem is not caused by scrolling.

I setup UITableViewCell with DispatchQueue.global(qos: .background).async, and this function is inside the cell itself.

--SensorRecordTableViewCell (UITableViewCell)--

func getNewLiveInfo(shedId: String, sensorCategory: String) {

        DispatchQueue.global(qos: .background).async {

            let id = self.shedId.cString(using: .utf8)
            let shed_id = UnsafeMutablePointer(mutating: id)

            let category = self.sensorCategory.cString(using: .utf8)
            let sensor_category = UnsafeMutablePointer(mutating: category)

            if let data = getliveInfo(shed_id, sensor_category) {
                let formatter = DateFormatter()
                formatter.locale = Locale(identifier: "en_US_POSIX")
                formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

                // record_id, sensor_id, sensor_category, sensor_value, read_time
                self.sensorRecord.recordId = String(cString: data.pointee!)
                self.sensorRecord.sensorId = String(cString: (data+1).pointee!)
                self.sensorRecord.sensorCategory = String(cString: (data+2).pointee!)
                self.sensorRecord.value = Double(String(cString: (data+3).pointee!))
                self.sensorRecord.time = formatter.date(from: String(cString: (data+4).pointee!))

                DispatchQueue.main.async {
                    self.setValueAndTime()

                }
                data.deallocate()
            }
        }     
    }

And call the function above from func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)

--UITableViewDelegate, UITableViewDataSource--

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        var cell = cell as! SensorRecordTableViewCell
        cell.getNewLiveInfo(shedId: shed.id!, sensorCategory: config.sensorRecordOrder[indexPath.row])
}

Finally, I setup the cell from func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: sensorCellId, for: indexPath) as! SensorRecordTableViewCell
        cell.setUpView(shedId: shed.id!, sensorCategory: config.sensorRecordOrder[indexPath.row])
            return cell
}

Is there any way to avoid the data exchange to the wrong row?

Upvotes: 0

Views: 292

Answers (1)

Liam
Liam

Reputation: 192

Here is a simple example to show what it should looks like, hope it helps.

class SensorRecord {
    var recordID: Int = 0
    var sensorID: Int = 0
}

class ViewController: UIViewController {

    private var dataSource = [SensorRecord]()

    override func viewDidLoad() {
        super.viewDidLoad()

        // request infos from your server
        getNewLiveInfo(completion: { (sensorRecords)
            // after the request success, reload data
            self.dataSource = sensorRecords
            self.tableView.reloadData()
        })
    }

}

// MARK: UITableViewDataSource
extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ID", for: indexPath)

        // let your cell to show datas from your server
        let sensorRecord = dataSource[indexPath.row]
        cell.update(with: sensorRecord)

        return cell
    }
}

Upvotes: 0

Related Questions