0

I am working on creating some custom Cocoa components. Currently I'm trying to figure out how to draw custom NSTextFields.

I have overridden the drawRect method on my subclass but when i start typing, i get a double rectangle like this https://i.stack.imgur.com/5FSYA.jpg.

Here is my drawRect method

- (void)drawRect:(NSRect)dirtyRect
{
    [NSGraphicsContext saveGraphicsState];
    [[NSBezierPath bezierPathWithRoundedRect:dirtyRect xRadius:5.0f yRadius:5.0f] setClip];
    [[NSColor grayColor] setFill];
    NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
    [NSGraphicsContext restoreGraphicsState];

    [NSGraphicsContext saveGraphicsState];
    NSRect rect = NSInsetRect(dirtyRect, 1.0f, 1.0f);
    [[NSBezierPath bezierPathWithRoundedRect:rect xRadius:5.0f yRadius:5.0f] setClip];
    [[NSColor whiteColor] setFill];
    NSRectFillUsingOperation(rect, NSCompositeSourceOver);
    [NSGraphicsContext restoreGraphicsState];
}

UPDATE:

I moved my drawing code into a NSTextFieldCell subclass as so

- (void)drawWithFrame:(NSRect)frame inView:(NSView *)controlView {
    [NSGraphicsContext saveGraphicsState];
    [[NSBezierPath bezierPathWithRoundedRect:frame xRadius:5.0f yRadius:5.0f] setClip];
    [[NSColor grayColor] setFill];
    NSRectFillUsingOperation(frame, NSCompositeSourceOver);
    [NSGraphicsContext restoreGraphicsState];

    [NSGraphicsContext saveGraphicsState];
    [[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 1.0f, 1.0f) xRadius:3.0f yRadius:3.0f] setClip];
    [[NSColor whiteColor] setFill];
    NSRectFillUsingOperation(frame, NSCompositeSourceOver);
    [NSGraphicsContext restoreGraphicsState];
}

But as soon as you are done editing it draws over the text, even though the cursor is still there? Any suggestions? I've tried drawing the title but it still happens.

Thanks for your help.

Answer:

NSCell Custom Highlight

By calling super drawInteriorWithFrame:inView I was able to stop the weird text disappearing issues.

Community
  • 1
  • 1
kwbock
  • 647
  • 5
  • 13
  • 1
    Why aren't use subclassing `NSTextFieldCell` instead? http://stackoverflow.com/questions/1938925/drawing-a-rounded-cornered-nstextfieldcell – trojanfoe Nov 05 '12 at 16:18

1 Answers1

1

It looks to me like you've ended up drawing inside the drawing of your superclass's (NSTextField's) drawRect: implementation. You haven't called super but it still manages to draw itself. I'm not sure why myself, but some NSControls such as text fields and buttons, when subclassed, will draw themselves regardless of whether or not you call drawRect: on them. For example, if you subclass a plain NSButton, implement drawRect: and don't call super, it'll draw the button anyways. Potentially over whatever you drew, which has caused confusion in the past. The easiest solution is to not subclass NSTextField, and see if there's another class you can subclass (like NSTextFieldCell mentioned in the comment).

Metabble
  • 11,773
  • 1
  • 16
  • 29
  • Ok that worked much better. i currently am drawing the textcell how i want to but as soon as you stop typing or focus leaves the cell, it draws my white inner rect (I'm drawing a bezierpath with gray and then drawing a 1px inset rect in white) it draws over the text. – kwbock Nov 05 '12 at 17:08
  • I'm not sure how `NSTextFieldCell` works, but it's probably something similar to your previous problem. Are you sure you need to draw a white background manually in `drawRect:`? See what happens if you just draw the outline, set the background color of the text field to white and clip it to its bounds. I think anything you draw in `drawRect:` will render over the text, so you shouldn't use it for the background. – Metabble Nov 05 '12 at 20:39