views:

340

answers:

1

I'm building a prototype iPad app that draws diagrams. I have the following view hierarchy:

UIView UIScrollView DiagramView : UIView TabBar NavigationBar

And a UIViewController subclass holding all that together.

Before drawing the diagram the first time I calculate the dimensions of the diagram, and set the DiagramView frame to that size, and the content size of the scrollview as well.

-(void)recalculateBounds
{
 [renderer diagram:diagram shouldDraw:NO];
 SQXRect diagramRect = SQXMakeRect(0.0,0.0,[diagram bounds].size.width,[diagram bounds].size.height);
 self.frame = diagramRect;
 [(UIScrollView*)[self superview] setContentSize:diagramRect.size];
}

I should disclose that the frame is being set to about 1500 x 3500 which i know is ridiculous. I just want to focus on some other parts of the app before I get into optimizing the render code.

This works beautifully, except that the rect being passed to drawRect is not the size that I set, and my drawing is getting clipped at the bottom. Its close the size i set, but bigger in width, and shorter in height.

Also of note, is the fact that if I force the frame to be much bigger than what I know the diagram needs, then the drawRect:rect is big enough, and no clipping occurs. Of course this has me wondering if the frame size needs to take into account some other screen real estate like the toolbars but my reading of the docs tells me the frame is in superview coordinates, which would be the scrollview so I reckon I do not to need to worry about such things.

Any idea what is causing this discrepancy?

+4  A: 

One thing to be careful of is that the maximum texture size on the non-3G S iPhones (and even in the Simulator on my MacBook Air) is 2048 x 2048. If you try to create a view or layer that exceeds this in either dimension, usually it simply won't display, or if it does it might be clipped in some way. Obviously, I haven't tested this on an iPad to see if it has the same texture size restrictions.

If you need to have a very large view like this, the recommended way to approach this is to use a CATiledLayer or a UIView backed by a CATiledLayer. You should be able to specify this in your UIView subclass by overriding the following method:

+ (Class) layerClass 
{
    return [CATiledLayer class];
}
Brad Larson
This is great information ... thanks much Brad!