Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTextField - Subclassing & drawRect cause text not to load

Trying to round out the border of an NSTextField (the little black box in the upper-left corner): http://cl.ly/image/2V2L1u3b3u0G

So I subclassed NSTextField:

MYTextField.h

#import <Cocoa/Cocoa.h>
@interface HATrackCounterField : NSTextField
@end

MYTextField.m

#import "HATrackCounterField.h"
@implementation HATrackCounterField
- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {}
    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor blackColor] setFill];
    [[NSBezierPath bezierPathWithRoundedRect:dirtyRect xRadius:3.0 yRadius:3.0] fill];
}

@end

Now its not showing the text-field text: http://cl.ly/image/1J2W3K431C04

I'm new at objective-c, it seems like this should be easy, so I'm probably just doing something wrong...

Thanks!

Note: I'm setting the text through a collection view, and I've tried setStringValue: at different points also to no avail.

like image 887
Alex Marchant Avatar asked Feb 19 '23 15:02

Alex Marchant


2 Answers

Your text-field's text isn't showing because you overwrite -drawRect and don't call [super drawRect:dirtyRect] in it.

In your case, I think the easiest way to do what you want is using clip mask: just let NSTextField perform drawing ant then clip the region:

- (void)drawRect:(NSRect)dirtyRect
{
    [NSGraphicsContext saveGraphicsState];
    [[NSBezierPath bezierPathWithRoundedRect:dirtyRect xRadius:3.0 yRadius:3.0] setClip];
    [super drawRect:dirtyRect];
    [NSGraphicsContext restoreGraphicsState];
}

In general it is better to subclass NSTextFieldCell instead to make custom drawing, because cells are responsible for drawing.

like image 135
Dmitry Avatar answered Mar 03 '23 01:03

Dmitry


For reference for future readers, this is probably how you should do it, by subclassing NSTextFieldCell:

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    NSBezierPath *betterBounds = [NSBezierPath bezierPathWithRoundedRect:cellFrame xRadius:CORNER_RADIUS yRadius:CORNER_RADIUS];
    [betterBounds addClip];
    [super drawWithFrame:cellFrame inView:controlView];
    if (self.isBezeled) { // optional, but provides an example of drawing a prettier border
        [betterBounds setLineWidth:2];
        [[NSColor colorWithCalibratedRed:0.510 green:0.643 blue:0.804 alpha:1] setStroke];
        [betterBounds stroke];
    }
}

I draw an additional bluish border here (though that seems to be unnecessary for your black box)

like image 30
Vervious Avatar answered Mar 03 '23 00:03

Vervious