views:

315

answers:

2

I am drawing content to a UITableViewCell and it is working well, but I'm trying to understand if there is a better way of doing this.

Each cell has the following components:

  • Thumbnail on the left side - could come from server so it is loaded async
  • Title String - variable length so each cell could be different height
  • Timestamp String
  • Gradient background - the gradient goes from the top of the cell to the bottom and is semi-transparent so that background colors shine through with a gloss

It currently works well. The drawing occurs as follows:

  • UITableViewController inits/reuses a cell, sets needed data, and calls

    [cell setNeedsDisplay]

  • The cell has a CALayer for the thumbnail - thumbnailLayer

  • In the cell's drawRect it draws the gradient background and the two strings

  • The cell's drawRect it then calls setIcon - which gets the thumbnail and sets the image as the contents of the thumbnailLayer. If the image is not found locally, it sets a loading image as the contents of the thumbnailLayer and asynchronously gets the thumbnail. Once the thumbnail is received, it is reset by calling setIcon again & resets the thumbnailLayer.contents

This all currently works, but using Instruments I see that the thumbnail is compositing with the gradient. I have tried the following to fix this:

  • setting the cell's backgroundView to a view whose drawRect would draw the gradient so that the cell's drawRect could draw the thumbnail and using setNeedsDisplayInRect would allow me to only redraw the thumbnail after it loaded --- but this resulted in the backgroundView's drawing (gradient) covering the cell's drawing (text).

  • I would just draw the thumbnail in the cell's drawRect, but when setNeedsDisplay is called, drawRect will just overlap another image and the loading image may show through. I would clear the rect, but then I would have to redraw the gradient.

  • I would try to draw the gradient in a CAGradientLayer and store a reference to it, so I can quickly redraw it, but I figured I'd have to redraw the gradient if the cell's height changes.

Any ideas? I'm sure I'm missing something so any help would be great.

Bump - anyone have any ideas for this?

A: 

Both UIView and CALayer have an opaque property. Any time you can set that to YES, there will be no compositing and drawing will be faster. If your thumbnail image has no transparency, it is an ideal candidate.

drawnonward
A: 

I started using setNeedsDisplayInRect. I still draw everything in drawRect but when I do, I check the rect that needs to be drawn and only update that rect. I also draw using CGLayers and keep them as ivars. When I need to redraw a section that hasn't changed, I use the stored CGLayer. The thumbnail is no longer a CALayer. For drawing selects I will have to use the selectedBackgroundView and reuse my CGLayers.

Brian