In a Cocoa Multi-Document Application I want to create an NSScrollView That will scroll the contents of myDocument window. I can’t do this by selecting all of the sub views in Interface builder and using the Layout>Make subviews of>Scroll View because it will only create a frame for the NSScrollView that will be as big as the limits of the frames of the sub views NOT the whole contents of the window. I want to include the white space around the sub views as well. Also I don’t want to do it in Interface Builder because once I’ve made a window sub view a child of an NSScrollView it can be resized but not moved in the NSScrollView. The bottom left corner is locked and can’t be dragged or changed in the Inspector. In other words once the subviews are made children of an NSScrollView they are cast in stone and changing the layout of the items is impossible. In MyDocument.h I declare an NSScrollView:
@interface MyDocument : NSDocument { NSScrollView* windowScrollView; } @end
In MyDocument.m I attempt to create a Scroll View for the window like this:
[self drawMySubviews]; }
Apple’s example in the Scroll View Programming Guide and the documentation for NSWindow tell me to do some retaining and releasing of objects but if I do the application crashes. Anyway all the app draws is a blank window with blank scroll bars. Setting the responder of the window and scrollView doesn’t help. How can I make this work?
Dude! Group whatever views you want in custom view (You can do this in IB) and then put the whole mess in a scroll view. You can reposition views within the custom view. Only the custom view is pinned to the corner of the clip view. Even thinking of abandoning IB for a triviality like this suggests a prior bias that isn’t warranted. —- Yes, I know that, I did it and it was the frustration of trying to make IB put everything where I wanted without playing god and deciding how much wider than my group of objects the custom view had to be, treating horizontal and vertical scrollbars differently, and the hassle of unpacking the subviews before adding another view and setting it up again that made me think that programatically creating a scrollview would be an easier way to deal with it.
I would suggest putting your custom view at the top level of the nib, and then creating a placeholder view in a scroll view, all in IB. Then in code you can grab the top-level custom view and insert it into the scroll view. This will give you all of the benefits of using IB but without the layout difficulty that comes with a view embedded in a scroll view in IB.
Not at my machine right now, but doesn’t NSScrollView expose a documentView outlet in IB? You wouldn’t even need to set the document view in code then. Just draw it in IB as a top-level NSView and connect it to the outlet. —- Um, no. NSScrollView does not expose a documentView outlet in IB. One line of code is nedded to set the document view of a scroll view.
[someScrollView setDocumentView:someView];
I have encountered more problems by putting all of the views in myDocument into a custom view and then making it a subview of a scroll view. The custom view has a color and it’s slightly opaque. This creates a small but noticable background color in myDocument’s window. I don’t want this, I want a white (transparent) background in myDocument’s window. This is much more noticable when printing. When I call
NSView *printView = myDocument window] contentView];
I solved the scroll bar problem by making the custom view (that groups the document window sub views) that is a child of a scroll veiw an IBOutlet and printing/saving it, not whe window content view. This also solves the opacity issue in printing and graphic images of myDocument but it is still somewhat opaque on my monitor. I added this code to the - (void)drawRect:(NSRect)rect method in the customView code, thinking that since it would be drawn first it would clear the background of the myDocument window:
[NSGraphicsContext saveGraphicsState]; CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort]; CGContextSetRGBFillColor (myContext, 0, 0, 0, 0); CGContextFillRect (myContext, CGRectMake (0, 0 , [self bounds].size.width, [self bounds].size.height)); [NSGraphicsContext restoreGraphicsState];
It doesn’t help