2
votes

I want to implement my own custom drawer completely by subclassing NSView and doing all my view drawing in that. I've created a custom NSView class that does hardly anything apart from implement initWithFrame: and drawRect: which I've got logging the frame/bounds of the NSView (which is reporting correctly). I've also instantiated this view and added it to the NSDrawer object in my application using setContentView: so that it uses my custom NSView.

However, this still draws a default drawer layout attached to the edge of my applications NSWindow. How do I override this default style so that I can draw my own drawer (!) in my custom, subclassed NSView without anything default being drawn by the OS? (So that I can control the design and size of the drawer myself, to basically emulate a tab bar that won't act strictly as a traditional drawer.)

2

2 Answers

1
votes

I made a custom drawer by subclassing NSWindow rather than NSDrawer. It was a lot of work. There is a private object, NSThemeFrame, that sits between a NSWindow and its contentView. To avoid using private API, you have to make a transparent window and let its contentView act like a NSThemeFrame. Matt Gallagher shows how: http://cocoawithlove.com/2008/12/drawing-custom-window-on-mac-os-x.html

1
votes

That frame is being drawn by the drawer's frame view. To do this, you need to use some private methods, and the easiest way is probably to use a custom subclass of NSDrawer. I do not know the specific methods used for drawers, but you can get a header for the class including private methods using class-dump.

Edit: This is what NSDrawer actually does.

NSDrawer is an opaque object that manages other objects. It creates a window using the private NSDrawerWindow class. Setting its content view sets the window's content view. The NSDrawerWindow class uses the private NSDrawerFrame class, which is a subclass of the private NSFrameView class, as its background and displays its content view inside that.

To change the frame, you need a way to change the frame view in the window. The easiest thing to do would be to get a header for NSDrawerWindow and add a category that overrides +frameViewClassForStyleMask: to return the class for your custom view. Your custom view should be a subclass of NSFrameView, which means you also need a header for that class.