views:

1169

answers:

2

I'm trying to programmatically create a window with custom contentView and one custom NSTextField control, but i'm having trouble getting this hierarchy of window and views to draw themselves.

I create a custom borderless window and override it's setContentView / contentView accessors. This seems to work fine and custom contentView's initWithFrame and drawRect methods get called causing contentView to draw itself correctly.

But as soon as i try programmatically adding custom NSTextField to contentView it doesn't get added or drawn. By saying custom i mean that i override it's designated initializer (initWithFrame:frame - only for custom font setting) and drawRect method which looks like this:

- (void)drawRect:(NSRect)rect {
    NSRect bounds = [self bounds];
    [super drawRect:bounds];
}

The custom contentView's initializer looks like this:

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self != nil) {
      // i want to draw itself to the same 
      // size as contentView thus i'm using same frame
      CustomTextField *textField = [[CustomTextField alloc] initWithFrame:frame];
      [self addSubview:textField];
      [self setNeedsDisplay:YES];
    }
    return self;
}

I've been strugling with this for few hours so any pointers are much appreciated. More code is available on request .)

+1  A: 

Your -drawRect: override seems wrong to me, why would you deliberately ignore the passed in rect argument? Why is this necessary?

As for why the text field is not appearing, it's most likely because you have not configured it. When you create an NSTextField in code, you don't get the same thing as the default instance that you get when you drag a text field onto a view in IB. You will need to configure the NSTextField and its NSTextFieldCell to get the appearance you desire.

I am using a programmatically added text field that I configure like this:

_textField = [[NSTextField alloc] initWithFrame:textFieldRect];
[[_textField cell] setControlSize:NSSmallControlSize];
[_textField setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
[_textField setBezelStyle:NSTextFieldSquareBezel];
[_textField setDrawsBackground:YES];
[_textField setBordered:YES];
[_textField setImportsGraphics:NO];
[_textField setAllowsEditingTextAttributes:NO];
[_textField setBezeled:YES];
[_textField sizeToFit];
[self addSubview:_textField];
[_textField setFrame:textFieldRect];
[_textField setAutoresizingMask:NSViewMinXMargin];
Rob Keniger
well i even tried not overriding the `drawRect` method or just simply drawing black rect. The reason why i'm ignoring the `rect` param is because it defines only the area which needs to be redrawn.For example when the cursor on the textfield blinks - OS sends drawRect with message with rect parameter that defines only the area of that cursor.Thanks for your advice, I'll try to follow it.
Eimantas
A: 

Thanks for your answers!

I found my own problem. The reason why drawRect wasn't being called is because custom textfield was drawn outside the frame of content view. I guess i forgot to mention crucial detail that i'm drawing window centered on the screen thus it's frame was with x/y offset.

To fill the window with it's content view I init contentView with same frame as window (meaning the same (x;y) offset from window's (0;0) point).

Now i'm just unable to write to custom text field, but that's another problem I think I'm able to handle.

Eimantas