0
votes

I have an NSView in IB which sits above the app window. I have a subclass of NSView (AddSource) which I assign to the NSView.

On awakeFromNib I instantiate the view:

//add a new Add Source class
addSourceView = [[AddSource alloc] initWithFrame:NSMakeRect(0.0, 959.0, 307.0, 118.0)];
[[winMain contentView] addSubview:addSourceView];

in addSourceView's drawRect method I am adding a white background to the view:

[[NSColor whiteColor] set];
NSRectFill(rect);
[self setNeedsDisplay:YES];//added this to see if it might solve the problem

In winMain's contentView I have a NSButton that when clicked slides the addSourceView onto the window:

NSRect addSourceViewFrame = [addSourceView frame];
addSourceViewFrame.origin.y = 841.0;
[[addSourceView animator] setFrame:addSourceViewFrame];

But it seems as if the app is painting over the IBOutlets I placed on the NSView in IB. If, in IB, I repoistion the NSView so that it is on screen when the app launches everything works fine, the IBOutlets are there as well as the background color.

I'm not sure why this is happening. I've done this before with no problems. I must be doing something different this time.

Thanks for any help.

Screen captures

*note - on the 3rd screen capture, when I say this is what the app looks like when opened, that's when I hard code the Y position of the NSView. When it is functioning correctly it should open as screen capture 1.

2
You seem quite confused.. randomly trying things like -setNeedsDisplay in drawRect is not the answer. Have you read the Hillegass book? - hooleyhoop
Confused, yep, but not the way you think. I dropped the setNeedsDisplay in there to see what would happen. - PruitIgoe
ok, i'll admit - i'm confused. It's not clear from your description if you create your AddSourceView in IB or -awakeFromNib - hooleyhoop
I have a class called AddSource (subclass of NSView). In IB, I create a NSView, give it AddSource as it's class and position it off window. On awakeFromNib I instantiate the class and in it's drawRect fill it with white. This happens without the user seeing the view. When the user clicks the add source button (+ sign) the view then slides down and the user can fill in the information needed (screen cap 3). But what I am getting is screen cap 2. - PruitIgoe
That's why I added setNeedsDisplay, I thought maybe because I was "painting" the view a color that I had to redraw the objects I had placed on it in IB (textfields and buttons). Edit: I can programmatically add the textfields and buttons (in the AddSource class's drawRect and it works fine but I would rather not have to do that. - PruitIgoe

2 Answers

0
votes

Most likely your buttons and custom view are siblings, i.e. they are both subviews of your window's content view. Since siblings are "Stacked" depending on the order in which they are added, when you add the view in code it is being added on top of the buttons. You should be able to fix it by explicitly specifying where the view should be positioned relative to its new siblings like so:

[[winMain contentView] addSubview:addSourceView positioned:NSWindowBelow relativeTo:nil];

which should place it below any existing subviews of your window's content view. Also, remove the setNeedsDisplay: line in drawRect, that leads to unncessary, possibly infinite, redrawing.

EDIT: OK I see what you're doing.

I would suggest creating a standalove view in the NIB by dragging a "Custom View" object into the left hand side (the vertically-aligned archived objects section) and adding your controls there, that should ensure the controls are actualy subviews of the view, then you can just create a reference to the archived view in code, and add/remove it dynamically as needed.

Honestly though, you should probably be using a sheet for these kinds of modal dialogs. Why reinvent the wheel, and make your app uglier in the process?

0
votes

You added TWO AddSource views to the window. You added one in IB - this view contains your textFields and buttons that are connected to the IBOutlets and it is positioned outside the window.

Then in -awakeFromNib you create another, blank AddSource view (containing nothing) and animate it into the window.

I can't recommend highly enough the Hillegass as the best introduction to IB and the correct way to build Cocoa Apps.

Also, Assertions can be useful to make sure what you think is happening is actually what is happening.

If you are certain you added a button to your view in IB, assert it is so:-

- (void)awakeFromNib {
      NSAssert( myButton, @"did i hook up the outlet?");
}

NSAssert is a macro that has zero overhead in a release build.

Calling [self setNeedsDisplay:YES] from -drawRect just causes the same -drawRect to be called again. This will give you big problems.