Misbehavior of UITableView willDisplayCell method

2020-04-12 04:09发布

There is a UITableView of posts.
Seen posts id's are saved in sqlite
I want to show, seen posts in orange color and others in black.
But when I set orange color for seen post in willDisplayCell method some cells are colored orange incorrectly, otherwise the print log ("Color it") is correct.

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    let post = postDataSource.posts[indexPath.row]
    print(post.id)
    let cellPost = cell as? PostListViewCell

    if post.isRead.boolValue == true {
        print("Color it")
        cellPost!.body.textColor = UIColor.orangeColor()
        cellPost!.title.textColor = UIColor.orangeColor()
    }
}

For instance, if just one post is seen, "Color it" is printed once. and it's correct. But some other cells are colored orange without "Color it" log.

2条回答
干净又极端
2楼-- · 2020-04-12 05:00

1.Understanding of Reusable table-view cell object

From Apple Documentation

For performance reasons, a table view’s data source should generally reuse UITableViewCell objects when it assigns cells to rows in its tableView(_:cellForRowAt:) method. A table view maintains a queue or list of UITableViewCell objects that the data source has marked for reuse. Call this method from your data source object when asked to provide a new cell for the table view.

This method dequeues an existing cell if one is available or creates a new one using the class or nib file you previously registered.

If no cell is available for reuse and you did not register a class or nib file, this method returns nil.

2.Usage of prepareForReuse()

From Apple Documentation

If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCell(withIdentifier:) . For performance reasons,

you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state.

The table view's delegate in tableView(_:cellForRowAt:) should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.

Another way to do manually resetting attributes of the cell which already described by @RJiryes.

查看更多
家丑人穷心不美
3楼-- · 2020-04-12 05:01

Try completing the if statement

 if (post.isRead.boolValue == true) {
    print("Color it")
    cellPost!.body.textColor = UIColor.orangeColor()
    cellPost!.title.textColor = UIColor.orangeColor()
}else{
    cellPost!.body.textColor = UIColor.blackColor()
    cellPost!.title.textColor = UIColor.blackColor()}
查看更多
登录 后发表回答