1

I have a custom UITableViewCell subclass which shows and image and a text over it. The image is downloaded while the text is readily available at the time the table view cell is displayed.

From various places, I read that it is better to just have one view and draw stuff in the view's drawRect method to improve performance as compared to have multiple subviews (in this case a UIImageView view and 2 UILabel views)

I don't want to draw the image in the custom table view cell's drawRect because

  1. the image will probably not be available the first time its called,
  2. I don't want to draw the whole image everytime someone calls drawRect.

The image in the view should only be done when someone asks for the image to be displayed (example when the network operation completes and image is available to be rendered). The text however is drawn in the -drawRect method.

The problems:

  1. I am not able to show the image on the screen once it is downloaded. The code I am using currently is-

    - (void)drawImageInView
    {
    //.. completion block after downloading from network
      if (image) { // Image downloaded from the network
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
        CGContextSetLineWidth(context, 1.0);
        CGContextSetTextDrawingMode(context, kCGTextFill);
    
        CGPoint posOnScreen = self.center;
        CGContextDrawImage(context, CGRectMake(posOnScreen.x - image.size.width/2,
                                           posOnScreen.y - image.size.height/2,
                                           image.size.width,
                                           image.size.height),
                                           image .CGImage);
        UIGraphicsEndImageContext();
      }
    }
    

I have also tried:

        UIGraphicsBeginImageContext(rect.size);
        [image drawInRect:rect];
        UIGraphicsEndImageContext();

to no avail.

  1. How can I make sure the text is drawn on the on top of the image when it is rendered. Should calling [self setNeedsDisplay] after UIGraphicsEndImageContext(); be enough to ensure that the text is rendered on top of the image?
Community
  • 1
  • 1
Devang
  • 1,531
  • 3
  • 22
  • 38

2 Answers2

0

You're right on the fact that drawing text will make your application faster as there's no UILabel object overhead, but UIImageViews are highly optimized and you won't probably ever be able to draw images faster than this class. Therefore I highly recommend you do use UIImageViews to draw your images. Don't fall in the optimization pitfall: only optimize when you see that your application is not performing at it's max.

Once the image is downloaded, just set the imageView's image property to your image and you'll be done.

Gianluca Tranchedone
  • 3,598
  • 1
  • 18
  • 33
  • The problem with using a UIImageView is that the its -drawRect method is not called. http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImageView_Class/Reference/Reference.html So I will have to use a couple of labels on top of the image view. I agree with not optimizing if not needed, but I do see some breaks in scrolling and thats why I am trying to optimize it. – Devang Jun 20 '13 at 09:10
  • I don't see how that is a problem. In your custom cell you can use the imageView as a standalone and then override -drawRect (of the cell) to draw texts. – Gianluca Tranchedone Jun 20 '13 at 09:27
  • The problem (atleast from my experimentations) is that imageView sits on top of the superview so anything done on the superview gets hidden when the image view is shown, even drawing text. – Devang Jun 20 '13 at 09:39
  • That's easy to solve: if you draw on the cell itself, you just have to calculate the correct rect in which you want to draw the text (you know what the image size will be by design, don't you?). Or you can draw on the cell's contentView instead. – Gianluca Tranchedone Jun 20 '13 at 09:49
  • The image is supposed to cover the whole cell bounds and then the text to be displayed over it. I think the problem with drawing in the content view will be the same, that the imageView will come over it. Thats why I was hoping to get a solution to be able to draw a text over an image. – Devang Jun 20 '13 at 10:19
0

Notice that the stackoverflow page you linked to is almost four years old, and that question links to articles that are almost five years old. When those articles were written in 2008, the current device was an iPhone 3G, which was much slower (both CPU and GPU) and had much less RAM than the current devices in 2013. So the advice you read there isn't necessarily relevant today.

Anyway, don't worry about performance until you've measured it (presumably with the Time Profiler instrument) and found a problem. Just implement your interface in the simplest, most maintainable way you can. Then, if you find a problem, try something more complicated to fix it.

So: just use a UIImageView to display your image, and a UILabel to display your text. Then test to see if it's too slow.

If your testing shows that it's too slow, profile it. If you can't figure out how to profile it, or how to interpret the profiler output, or how to fix the problem, then come back and post a question, and include the profiler output.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848