draw outside of UIView's bounds from drawRect

Kenny Winker picture Kenny Winker · Nov 29, 2010 · Viewed 9.3k times · Source

My question is very similar to this one Not drawing outside bounds when clipToBounds=NO which received no clear answer.

Basically I have a UIView, and I want to draw a line from the center of it, to the edge of the screen. Calculating where these points are is easy, using [self convertPoint:(CGPoint){0,0} fromView:[self superview]]; (which finds the origin with respect to my view's superview. But when I draw a line from my view's drawRect: it gets clipped at my view's bounds.

Is there a way to draw outside of my view's bounds? I've tried changing the clipsToBounds property, but it doesn't seem to have any effect.

I can't draw my lines from the superview because I need to do this with multiple views and some will be in front of others... figuring out the layer from the superview's drawRect seems like a bad idea.

Similarly, I don't think I can just resize my view's bounds to include the entire screen, because my views need to be dynamically re-sizable... the bounds would have to be HUGE (>20,000 points square) for this to work.

Answer

slycrel picture slycrel · Nov 29, 2010

I wouldn't recommend ever drawing outside of a view's bounds. Either your view needs to resize automatically to include your drawing or you need to have transparent overlapping views. Or both. I can't think of a situation that either of these cases wouldn't cover, but I may lack imagination. =)

Likely what is happening currently is that when the super view gets redrawn it tells the super view that it needs redrawn, resulting in erasing the drawing you are doing outside. It's been a while, anyone more knowledgeable can (should!) correct me here if I'm wrong.

I don't know if "Quartz Debug" (from the standard apple developer tools install, /Developer/Applications/Performance Tools/Quartz Debug) works in the simulator, but it's worth a try. It has a mode that will show you when and how often redrawing takes place, with a border and optional delay on the refreshes.

You can do what you are asking, but you need to force redraw your sub-views every time you go outside the sub-view's bounds, meaning that your super-view needs to manually draw it's children inside of it's draw function. Essentially you would be throwing out apple's drawing paradigm and simply causing your sub-views to act like a drawing extension of your main view anyway.

Additionally, if your ranges are so dynamic you may want to consider drawing in percentages of the screen or super-view rather than in points, it may make more sense to code.