A: 

This code of yours looks rather more elaborate than it needs to be. Check out NSCenterScanRect(), and NSRectFillListWithColors(). Also, it's rather wasteful to create and discard paths in -drawRect:.

NSResponder
Great! And the alternatives are what, exactly?
Philip Regan
So, I had some time to look into your answer, but I don't see how NSCenterScanRect nor NSRectFillListWithColors() is going to help me with the issues listed at the top of my (self-admittedly robust) question.
Philip Regan
I don't think you're going to see how anything is going to help you until you sit down in front of that documentation and really put some effort into learning what you need to do before you blindly try to do it.
Azeem.Butt
I'm not trying to "blindly" do it; I'm just new. I honestly thought I had this correct and I didn't. But, please don't make assumptions about my working methods. Thanks
Philip Regan
+6  A: 

I think you are misunderstanding the way drawRect: and its argument works:

The message drawRect: is sent by cocoa whenever your view or parts of it need to be redrawn. The CGRect argument is the bounding box of all updated areas for the current redraw. That means that you should not derive any positions of objects within your view from this rectangle. It is only passed to the method to allow for optimized drawing: if something is completely outside of this rectangle it does not need to be redrawn.

You should calculate all positions within your view from the views coordinate system: [self bounds]. This does not change each time drawRect: is performed and gives you an origin and size for the contents of the view.

There are a couple of other issues with your code (for instance, don't call setFrame: from within drawRect:) but I think you should first get the coordinates right and then look further into how to calculate pixel-aligned coordinates for your rectangles.

Nikolai Ruhe
+1 I think the use of the rect parameter is definitely causing a lot of confusion here. You're forcing things right at the boundary when they should actually be drawn off screen and clipped.
Rob Napier
Then, I guess I'm not understanding the relationship between the view and my model filled with custom classes. My model has an editing area larger than the viewable area. Objects can, and will, be everywhere and I need to support live scrolling. I called 'setFrame:' to the Model's Rect because it sorted out the scrollbars for me. I didn't see any other way of managing scrolling than to draw the complete set of data each time. (Response continued in next comment...)
Philip Regan
In my other IDE (REALbasic), I had *direct* access to the scrollbars and their properties, so it was a cinch to get the offset values and draw accordingly; I only drew what was viewable and within the context of the viewing area. If I wanted an object at pixel 0, then it simply got drawn there. So, how do I duplicate that here? I feel like I'm missing fundamental. Thanks for the responses!
Philip Regan
In Cocoa you draw everything in the view's `bounds`. The origin of this rect is usually at 0, 0, so you can draw everything like you used to do. The parts you need to draw (the visible region, or rather, the region that needs redisplay) can be determined from the argument you get passed in `drawRect:`.
Nikolai Ruhe
Philip Regan: Positioning your drawing within the visible area is the scroll view's job. Your view should not know or care whether it is in a scroll view, because the scroll view and clip view will reposition your drawing and clip to the visible area for you. All you need to do is draw, as if no scroll view exists.
Peter Hosey