Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView Drawing Best Practices

My application is able to do some simple figure's drawing (until I get a more stable code, I am sticking with only one figure) and it's also able to re-size them. The code I use to create a UIView is the following :

- (void)drawRect:(CGRect)rect
{    
    CGContextRef context = UIGraphicsGetCurrentContext();

    [self setContextFillColor:context];
    [self setContextStrokeColor:context];
    [self setLineWidth:context];

    CGFloat lineThickness = [self lineWidth] ;
    CGFloat halfLineThickess = lineThickness / 2.0f;

    CGContextAddRect(context, CGRectMake(halfLineThickess,halfLineThickess, rect.size.width - lineThickness, rect.size.height - lineThickness));

    CGContextDrawPath(context, kCGPathEOFillStroke);
}

Which gives me, with an input size of (100.0f,100.0f), this:

enter image description here

This figure is inside a "container" UIView which in turn is inside an UIScrollView. My problem with this is when I am re-sizing my figure and I reach sizes of around 1000*1000 (my "container" is 20,000*20,000), I start receiving memory warnings and the application finally gives up. So my questions are:

1) Should I consider putting a maximum size for the UIView?

2) How could I use the instruments to track this kind of problems, and see where the problem is coming (or where is the heavy lifting being done).

3) Should I use some kind of caching like this?

4) Are there some general best practices to consider, when drawing an UIView?

5) Should I consider CALayer, although I need to listen to touches?

The re-sizing of the UIView is based mostly on this.

like image 388
Rui Peres Avatar asked Oct 17 '12 13:10

Rui Peres


2 Answers

1) I think that size it's not a problem if you are using right approach.

2) You should use Instruments take a look at WWDC videos about tracking memory problems

3,4) I think that - (void)drawRect:(CGRect)rect it's not a good practice. Will be better if you will look at drawing CALayer. You can use custom CGMutablePathRef for drawing.

So UIView is good for processing touches but not good for drawing shapes.

like image 30
Danil Avatar answered Nov 16 '22 00:11

Danil


You should not create a UIView this large. It's just too big. This kind of problem is what CATiledLayer is designed to address. Basically you'll need to keep track of bounding boxes for your shapes, and use those bounding boxes to figure out which tiles intersect which shapes. When the system asks for a given tile, then you draw all the shapes that intersect it. For very large and complex shapes, you can further optimize by splitting up the shape, but often this isn't needed.

like image 76
Rob Napier Avatar answered Nov 16 '22 02:11

Rob Napier