Reputation: 18508
I am developing in Cocoa, and I am currently having problems with filling the background of a NSWindowController
.
I understand that subclassing is the way forward if you want to customise your cocoa app. So I created a custom NSView
named whiteView and added this view as a subview to my windowController
's contentView
; however, there are some issues with completely filling the background of the window. Can anyone explain how I can have the color cover the complete surface area of the window's frame pls. Thank you
These are the results that I have so far.
1) This is the window when I leave it as it is, notice the white color only having covered half of the window.
2)Here is the same window again when I adjust the window far to the right and bottom. The white screen seems to stretch enough so that it covers the elements.
This is how I create the custom view
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
[[NSColor whiteColor] set];
NSRectFill([self bounds]);
}
And this how I achieve plaster the view onto my window.
WhiteView *whiteBackgroundView = [[WhiteView alloc] initWithFrame:self.window.frame];
[self.window.contentView addSubview:whiteBackgroundView positioned:NSWindowBelow relativeTo:self.window.contentView];
What do I need to do to correctly allow for my window's background to be fully covered in white?
Upvotes: 0
Views: 138
Reputation: 90531
First, the simple solution is to use -[NSWindow setBackgroundColor:]
to just set the window's background color. No need for a view.
If you're still interested in how to fix the view-based approach, probably what's wrong is that you haven't set the autoresizing mask of the view to make it follow the changes in the window size. For example, you could do [whiteBackgroundView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]
.
However, you could also set the whiteBackgroundView
as the window's contentView
rather than as a subview of it. The window's content view is always kept at the size necessary to fill the window's content rect. All of the other views of your window would be subviews of the white background view. In my opinion, this is better than making it a sibling that just happens to be at the back. Using relative ordering among siblings views to achieve a particular rendering order is a hack.
Finally, there's no reason to invoke super
's implementation in your -drawRect:
if the superclass is NSView
itself. NSView
doesn't do any drawing in its -drawRect:
. Also, your subclass takes over full responsibility for the entire drawn contents of its bounds, so you'd overdraw whatever super
had drawn, anyway. (Also, you need only fill dirtyRect
rather than [self bounds]
.)
While you're at it, since your class fills its bounds, you should override -isOpaque
to return YES
for optimization.
Update: regarding the frame of the view: if it's not going to be the window's content view, then you want to set its frame to be its prospective superview's bounds. So, you should have used self.window.contentView.bounds
if you wanted whiteBackgroundView
to fill the content view.
More generally, if you want the content rect of a window, you would do [window contentRectForFrameRect:window.frame]
. But if a view is going to be a window's content view, there's no need to set its frame to anything in particular. It will be resized automatically.
Update 2:
To transfer the view hierarchy from the original content view to the new content view (when you're making the white background view the content view):
NSArray* subviews = [self.window.contentView.subviews copy];
[subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[whiteBackgroundView setSubviews:subviews];
[subviews release];
(Written for manual retain-release. If using ARC, just drop the -release
invocation.)
Regarding the frame to use, as mentioned in the first update: keep in mind that the view's frame should be expressed in the coordinate system of its superview. So, as I said, self.window.contentView.bounds
would work if you're putting the new view into the content view. The window's frame and content rect are in screen coordinates. They would be completely incorrect for positioning a view.
Upvotes: 2