Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setNeedsDisplay doesn't always call drawRect

I have a custom view in a custom table cell. Every time a specific property on the custom view is changed I call [self setNeedsDisplay] which redraws the view in - (void)drawRect:(CGRect)rect. That property is set in the table view delegate's tableView:cellForRowAtIndexPath:. But when the table view is larger than the screen and cells have to be reused, drawRect isn't called every time setNeedsDisplay is. Especially when I flick the table quickly . Slow scrolling works fine. This leads to the information in the first and last cells often being incorrect.

In the log I can see that normally, for every call to setNeedsDisplay there is a call to drawRect, but when I scroll the table view quickly there are more calls to setNeedsDisplay than drawRect. Surely there should be a one-to-one ratio here.

I use the same custom view in a normal UIView, and it redraws perfectly every time I call setNeedsDisplay. The problem seems isolated to table views and reusing cells.

Does anyone know what's going on here? Is there any other way to force the custom view to redraw itself?

like image 679
kareman Avatar asked May 17 '09 18:05

kareman


2 Answers

I think I struggled with this issue for almost a week before I found the problem. Here it is, and I kid you not:

The pointer to this custom view was defined in the .m file instead of the .h file, making it a class variable instead of an instance variable.

And yes I am very, very embarrassed.

like image 143
kareman Avatar answered Oct 01 '22 18:10

kareman


setNeedsDisplay will only call drawRect: if the view is visible, otherwise it invalidates the view's layer and drawRect: will be called when it does become visible.

When scrolling through a table view, the table view will request cells in the hopes of adding them to the view. If scrolling fast enough, some cells will take too long to prepare and by the time they are ready the location they should be positioned is offscreen. In these cases, the table view discards them instead of adding them to the scroll view (and thus drawRect: will not be called)

like image 34
rpetrich Avatar answered Oct 01 '22 19:10

rpetrich