Pregunta

I want to overwrite the NSSearchField class and make it seems like enter image description here

I have looked into the Apple's Document, and found out that NSSearchField is inherited from NSTextField, which is inherited from NSControl, and NSControl itself is inherited from NSView.

So, NSTextField could correspond to setShadow: method, however, I've tried to set an NSShadow on the NSSearchField instance, but nothing happened actually.

Could anyone tell to how to get the shadow effect? Thanks~

¿Fue útil?

Solución

NSTextField with NSShadow

// Modify theTextField so that its NSShadow will be visible.
theTextField.wantsLayer = YES ;
theTextField.bezeled = NO ;
theTextField.drawsBackground = NO ;

NSShadow* redShadow = [NSShadow new] ;
redShadow.shadowOffset = NSMakeSize(2, 2) ;
redShadow.shadowColor = [NSColor redColor] ;
theTextField.shadow = redShadow ;

That results in: Grey text, red shadow

In my experience with NSShadows and NSTextFields/NSSearchFields, the shadow doesn't appear unless the NSTextField is not bezeled and does not draw its background, and the blinking cursor is shadowed along with the text before it.

Edit:

Subclass NSSearchField, override drawRect:

- (void) drawRect:(NSRect)dirtyRect {
    NSShadow* redShadow = [NSShadow new] ;
    redShadow.shadowOffset = NSMakeSize(2, -2) ;
    redShadow.shadowColor = [NSColor redColor] ;

    [NSGraphicsContext saveGraphicsState] ;
    self.wantsLayer = YES ;     // or NO
    [redShadow set] ;
    [super drawRect:dirtyRect] ;
    [NSGraphicsContext restoreGraphicsState] ;
}

That results in: wantsLayer = YES wantsLayer = NO. I assume you don't want the magnifying glass icon or X button to have shadows, so you could:

Add a second NSSearchField behind the original

This would probably be easier to do in Interface Builder, but here's code that would accomplish this in an NSSearchField subclass.

- (void) awakeFromNib {
    [super awakeFromNib] ;

    NSSearchField* shadowSearchField = [NSSearchField new] ;
    [self.superview addSubview:shadowSearchField  positioned:NSWindowBelow  relativeTo:self ] ;
    shadowSearchField.translatesAutoresizingMaskIntoConstraints = NO ;
    shadowSearchField.editable = NO ;

    float horizontalOffset = -2 ;
    float verticalOffset   = -2 ;
    [self.superview addConstraint: [NSLayoutConstraint constraintWithItem:self  attribute:NSLayoutAttributeLeading  relatedBy:NSLayoutRelationEqual  toItem:shadowSearchField  attribute:NSLayoutAttributeLeading  multiplier:1  constant:horizontalOffset ] ] ;
    [self.superview addConstraint: [NSLayoutConstraint constraintWithItem:self  attribute:NSLayoutAttributeTop      relatedBy:NSLayoutRelationEqual  toItem:shadowSearchField  attribute:NSLayoutAttributeTop      multiplier:1  constant:verticalOffset ] ] ;
    [self.superview addConstraint: [NSLayoutConstraint constraintWithItem:self  attribute:NSLayoutAttributeWidth    relatedBy:NSLayoutRelationEqual  toItem:shadowSearchField  attribute:NSLayoutAttributeWidth    multiplier:1  constant:0 ] ] ;
    [self.superview addConstraint: [NSLayoutConstraint constraintWithItem:self  attribute:NSLayoutAttributeHeight   relatedBy:NSLayoutRelationEqual  toItem:shadowSearchField  attribute:NSLayoutAttributeHeight   multiplier:1  constant:0 ] ] ;
}

That results in: with focusRing and without focusRing, which seem closest to what you want, if you can tweak the position and color of the second NSSearchField.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top