Set Border for Nstextfield

Change border color of NSTextField

Use NSBezierPath

- (void)drawRect:(NSRect)dirtyRect
{
NSPoint origin = { 0.0,0.0 };
NSRect rect;
rect.origin = origin;
rect.size.width = [self bounds].size.width;
rect.size.height = [self bounds].size.height;

NSBezierPath * path;
path = [NSBezierPath bezierPathWithRect:rect];
[path setLineWidth:2];
[[NSColor colorWithCalibratedWhite:1.0 alpha:0.394] set];
[path fill];
[[NSColor redColor] set];
[path stroke];

if (([[self window] firstResponder] == [self currentEditor]) && [NSApp isActive])
{
[NSGraphicsContext saveGraphicsState];
NSSetFocusRingStyle(NSFocusRingOnly);
[path fill];
[NSGraphicsContext restoreGraphicsState];
}
else
{
[[self attributedStringValue] drawInRect:rect];
}
}

Output:

Sample Image

Sample Image

Custom Border on NSTextField

You should probably read the documentation for the NSCell. It says that you must draw the border in the draw(withFrame:in) function and you must invoke drawInterior(withFrame:in:) if you override draw(withFrame:in). Additionally you must override cellSize and return the appropriate size that takes your new border into account. I updated the example to the full solution. Created a sample project on Github

/**
Creates an custom border, that is just a line underneath the NSTextField.
*/
class CustomBorderTextFieldCell: NSTextFieldCell {
// How thick should the border be
let borderThickness: CGFloat = 3

// Add extra height, to accomodate the underlined border, as the minimum required size for the NSTextField
override var cellSize: NSSize {
let originalSize = super.cellSize
return NSSize(width: originalSize.width, height: originalSize.height + borderThickness)
}

// Render the custom border for the NSTextField
override func draw(withFrame cellFrame: NSRect, in controlView: NSView) {
// Area that covers the NSTextField itself. That is the total height minus our custom border size.
let interiorFrame = NSRect(x: 0, y: 0, width: cellFrame.width, height: cellFrame.height - borderThickness)

let path = NSBezierPath()
path.lineWidth = borderThickness
// Line width is at the center of the line.
path.move(to: NSPoint(x: 0, y: cellFrame.height - (borderThickness / 2)))
path.line(to: NSPoint(x: cellFrame.width, y: cellFrame.height - (borderThickness / 2)))
NSColor.black.setStroke()
path.stroke()

// Pass in area minus the border thickness in the height
drawInterior(withFrame: interiorFrame, in: controlView)
}
}

This is the result
Custom NSTextField Border

Change NSTextField border and BG color while editing

You can set the delegate of NSTextField:

nameTextField.delegate = self

then you can set a different state:

func control(control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {
nameTextField.bezeled = true
nameTextField.backgroundColor = NSColor.textBackgroundColor()

return true
}
func control(control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {
nameTextField.bezeled = false
nameTextField.backgroundColor = NSColor.windowBackgroundColor()

return true
}

EDIT:

I think you can subclass NSTextField and override the becomeFirstResponder and the resignFirstResponder, then you know the NSTextField has the focus or not.

How to draw border around NSTextView

Another alternative is to create a separate class for the text view and use draw() to provide the frame:

class TextView: NSTextView {
override func draw(_ rect: NSRect) {
super.draw(rect)
let border:NSBezierPath = NSBezierPath(rect: bounds)
let borderColor = NSColor.black
borderColor.set()
border.lineWidth = 2.0
border.stroke()
}
}

Styling of NSTextField

Set new CALayer and play with isBezeled and isBordered properties before setting colors.

let field = NSTextField()
field.layer = CALayer()
field.wantsLayer = true
field.isBezeled = false
field.isEditable = true
field.isBordered = true
field.backgroundColor = NSColor.white
field.layer?.borderColor = NSColor.gray.cgColor
field.layer?.backgroundColor = NSColor.white.cgColor
field.layer?.borderWidth = 1
field.layer?.cornerRadius = 5

NSTextField custom background, border and corners

There can be many ways to do :

Subclass NSButton and if required also subclass NSButtonCell and override these methods

  1. -(void)drawRect:(NSRect)rect {

    }

  2. drawText:withFrame:inView:

  3. drawImage:withFrame:inView:.

NSTextField with rounded corners?

You are doing almost everything correct. You just need to change the textField's cell and radius which match. Take a look at this:

-(void)awakeFromNib {

[[self cell] setBezelStyle: NSTextFieldRoundedBezel];
}

- (void)drawRect:(NSRect)dirtyRect
{

NSRect blackOutlineFrame = NSMakeRect(0.0, 0.0, [self bounds].size.width, [self bounds].size.height-1.0);
NSGradient *gradient = nil;
if ([NSApp isActive]) {
gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.24 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.374 alpha:1.0]];
}
else {
gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithCalibratedWhite:0.55 alpha:1.0] endingColor:[NSColor colorWithCalibratedWhite:0.558 alpha:1.0]];
}

[gradient drawInBezierPath:[NSBezierPath bezierPathWithRoundedRect:blackOutlineFrame xRadius:10 yRadius:10] angle:90];

}

This is working for me nicely.



Related Topics



Leave a reply



Submit