简体   繁体   中英

cellForRow returns nil - swift 3

I'm calling a JSON and saving the data on a array, after that reload the tableView, when i use dequeueReusableCell everything works, but when i change to cellForRow i get a crash every time i set the cell. The reason im using cellForRow is that i need to change the image of the cell after the user clicks on it but if i use dequeueReusableCell i get multiple changes (since the cell is always reused).

I'm getting a crash at the let cell = tableView.cellForRow(at: indexPath) as! TicketTableViewCell let cell = tableView.cellForRow(at: indexPath) as! TicketTableViewCell . I already done a search but nothing helped me.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.cellForRow(at: indexPath) as! TicketTableViewCell

    //let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TicketTableViewCell

    cell.date.text = arrDate[indexPath.row].date

    //Top Bottom Space.
    let maskLayer = CAShapeLayer()
    let bounds = cell.bounds
    maskLayer.path = UIBezierPath(roundedRect: CGRect(x: 2, y: 2, width: bounds.width-4, height: bounds.height-4), cornerRadius: 2).cgPath
    cell.layer.mask = maskLayer

    return cell
}

Go back to using dequeueReusableCell

in didSelectRowAt change the image you want to use, or set a value somewhere in your data set, and reload that row

Make sure that the cellForRowAt method uses the updated image or flag that you have set, and redraw the cell.

From within the data source method tableView(:cellForRowAt:) you can't use tableView.cellForRow(at: indexPath) because the second method just gives you back the cell that you previously gave it in the first method.

It's meant to get back a cell from the table view if you have an index path. You can't get around the table view's view-reuse, you have to use dequeue.

If the problem is you "get multiple changes (since the cell is always reused)" you need to ensure the cell is properly prepared for reuse, and/or that it's only setup once.

I'm not sure what your implementation is, but when your view controller gets called that the user has clicked on the cell (from a button or gesture recognizer) you should pass the cell itself, because if you have the cell you can call tableview.indexPathForCell() and know which indexPath was clicked, so you will know what data to update this cell with. Hope this helps.

EDIT: (Cell is 'selected' in the sense you keep track, not the cell's selected property, if you want to use that it's all different). You should also track the currently selected index and format the cell differently in the data source method, in case the user scrolls the selected cell off-screen and back it should still be selected.

Having the data source method check if a cell is selected is important because it would also let you just indiscriminately reload any cells that you think might have a change. But that's not great practice (but simple and fine!) better is if you have the cell you can set its properties directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM