To draw a custom view with its one or more corners round, all you need to do is draw a bezier path of the required shape in the view’s drawRect: method.
Also, this can be used to customize any NSView subclassed objects as NSTextView, NSTextField etc.
Here I present the code to create a text field with any one round corner as shown in the image below. The code can be easily changed to create more than one round corners of a view.
These are four different text fields in the figure each with its different corner rounded. You can create similar text field using the code below.
// Set the background color of your view to transparent and no focus ring as it will be of rectangular shape.
[self setBackgroundColor:[NSColor clearColor]];
[self setFocusRingType:NSFocusRingTypeNone];
// Set the corner curve radius
[NSGraphicsContext saveGraphicsState];
CGFloat cornerRadius = 20;
Drawing the bezier path
// Draw top left round corner
NSBezierPath *path = [NSBezierPath bezierPath];
[path moveToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds))];
// Draw side border and a top-left rounded corner
NSPoint topLeftCorner = NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds));
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds) + cornerRadius)];
[path curveToPoint:NSMakePoint(NSMinX(self.bounds) + cornerRadius, NSMinY(self.bounds)) controlPoint1:topLeftCorner
controlPoint2:topLeftCorner];
// Draw top border, right border and bottom border
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds))];
Set color and fill the path
[[NSColor redColor]set];
[path fill];
[NSGraphicsContext restoreGraphicsState];
All you need is copy the above code in the drawRect: method of your custom text field (i.e subclass of NSTextField) to get a text field with top left corner round (first text field in the image above).
Now , to create a text field with its top right corner rounded, the code will be same but you only need to draw the bezier path a bit differently. The points where the curve will be drawn this time is top right corner. So the steps to draw the bezier path in this case are:
// Draw top right round corner
NSBezierPath *path = [NSBezierPath bezierPath];
[path moveToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];
// Draw top border and a top-right rounded corner
NSPoint topRightCorner = NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds));
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds)-cornerRadius, NSMinY(self.bounds))];
[path curveToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds)+cornerRadius)
controlPoint1:topRightCorner
controlPoint2:topRightCorner];
// Draw right border, bottom border and left border
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];
Similarly the bezier path for Bottom Left Round corner and Bottom Right Round corner can be drawn as:
// Draw bottom left round corner
NSBezierPath *path = [NSBezierPath bezierPath];
[path moveToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds))];
// Draw left border and a bottom-left rounded corner
NSPoint bottomLeftCorner = NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds));
[path lineToPoint:NSMakePoint(NSMinX(self.bounds)+cornerRadius, NSMaxY(self.bounds))];
[path curveToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds)-cornerRadius)
controlPoint1:bottomLeftCorner
controlPoint2:bottomLeftCorner];
// Draw bottom border, right border and top border
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds))];
// Draw bottom right round corner
NSBezierPath *path = [NSBezierPath bezierPath];
[path moveToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds))];
// Draw bottom border and a bottom-right rounded corner
NSPoint bottomRightCorner = NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds));
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMaxY(self.bounds)-cornerRadius)];
[path curveToPoint:NSMakePoint(NSMaxX(self.bounds)-cornerRadius, NSMaxY(self.bounds))
controlPoint1:bottomRightCorner
controlPoint2:bottomRightCorner];
// Draw right border, top border and left border
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMaxY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMinX(self.bounds), NSMinY(self.bounds))];
[path lineToPoint:NSMakePoint(NSMaxX(self.bounds), NSMinY(self.bounds))];
This way you can draw a custom view with any of its corner round.
Written By: Neha Gupta, Software Engineer, Mindfire Solutions