Drawing in Cocoa, Objective C using NSBezierPath

NSBezierPath appendBezierPathWithArcWithCenter

Rainbows-NSBezierPath

@implementation RainbowView

-(void)drawRect:(NSRect)dirtyRect
{
    [[NSColor blackColor] set];
    NSRectFill(dirtyRect);
    
    [[NSColor whiteColor] set];
    NSBezierPath * path = [NSBezierPath bezierPath];
    [path setLineWidth:10.5];
    
    float xMargin = 0;
    float yMargin = 0.0;

    
    float maxWidth = dirtyRect.size.width - 2 * xMargin;
    float maxRadius = 0.0;
    float arcRadius = 0.0;
    
    NSPoint arcBegin;
    NSPoint midPoint;
    
    
    float y1;
    float midx, midy;
    
    y1 = yMargin;
    midy = yMargin;
    
    float r,g,b;
    float alpha = 0.2;
    for (int j = 0; j< 10; j++)
    {
    for (int i=0; i< maxWidth - 10; )
    {
        if ((i == 120) ||
            (i == 220) ||
            (i == 420) ||
            (i == 720)||
            (i == 920))
            
        {
            i = i + 10;
        }
        path = [NSBezierPath bezierPath];
        [path setLineWidth:0.5];
        r = (float)(arc4random()% 255) / 255;
        g = (float)(arc4random()% 255) / 255;
        b = (float)(arc4random()% 255) / 255;
        maxRadius = (i+maxWidth)/2 - i;
        arcRadius = arc4random() % (int)maxRadius;
        
        if (arcRadius < 75)
        {
            [[NSColor colorWithCalibratedRed:(float)10/255 green:(float)10/255 blue:(float)237/255 alpha:alpha] set];
        }
        else if (arcRadius < 150)
        {
            [[NSColor colorWithCalibratedRed:(float)255/255 green:(float)105/255 blue:(float)180/255 alpha:alpha] set];
        }
        else if (arcRadius < 250)
        {
            [[NSColor colorWithCalibratedRed:(float)0/255 green:(float)255/255 blue:(float)255/255 alpha:alpha] set];
        }
        else if (arcRadius < 350)
        {
            [[NSColor colorWithCalibratedRed:(float)255/255 green:(float)105/255 blue:(float)180/255 alpha:alpha] set];
        }
        else if (arcRadius < 450)
        {
            [[NSColor colorWithCalibratedRed:(float)255/255 green:(float)165/255 blue:(float)10/255 alpha:alpha] set];
        }
        else if (arcRadius < 525)
        {
            [[NSColor colorWithCalibratedRed:(float)120/255 green:(float)255/255 blue:(float)10/255 alpha:alpha] set];
        }
        else if (arcRadius < 550)
        {
            [[NSColor colorWithCalibratedRed:(float)255/255 green:(float)255/255 blue:(float)10/255 alpha:alpha] set];
            
        }
        else if (arcRadius < 650)
        {
            [[NSColor colorWithCalibratedRed:(float)173/255 green:(float)255/255 blue:(float)47/255 alpha:alpha] set];
        }
       else
        {
            [[NSColor colorWithCalibratedRed:(float)255/255 green:(float)255/255 blue:(float)19/255 alpha:0.2] set];
        }
        midx = xMargin + i + arcRadius;
        arcBegin = NSMakePoint(xMargin+i, y1);
        midPoint = NSMakePoint(midx, midy);
        [path moveToPoint:midPoint];
        [path appendBezierPathWithArcWithCenter:midPoint radius:arcRadius startAngle:0 endAngle:180];
        [path stroke];
        i = i+1;
    }
    }
}
@end

Drawing in Swift using NSBezierPath

//
//  CustomView.swift
//  SwiftBezierPath
//
//  Created by Debasis Das on 6/2/14.
//  Copyright (c) 2014 KnowStack. All rights reserved.
//
import Cocoa
import Foundation
class CustomView: NSView{   
    override func drawRect(dirtyRect: NSRect)
    {
        println(dirtyRect)
        var bPath:NSBezierPath = NSBezierPath(rect: dirtyRect)
        println(bPath)
        let fillColor = NSColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)
        fillColor.set()
        bPath.fill()
        
        let borderColor = NSColor(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
        borderColor.set()
        bPath.lineWidth = 12.0
        bPath.stroke()
       
        let circleFillColor = NSColor(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)
        var circleRect = NSMakeRect(dirtyRect.size.width/4, dirtyRect.size.height/4, dirtyRect.size.width/2, dirtyRect.size.height/2)
        var cPath: NSBezierPath = NSBezierPath(ovalInRect: circleRect)
        circleFillColor.set()
        cPath.fill()
    }
}

Swift_NSBezierPath

Drawing in Cocoa, Objective C using NSBezierPath

In the examples given below. We have created Custom View (Sub Class of NSView) and set the Custom Class of our NSView instance to the Custom View.
The Custom View Subclass implements the drawRect method

Cocoa_CG6
 - (void)drawRect:(NSRect)dirtyRect
 {
      [super drawRect:dirtyRect];
       // [self drawSquareBackgroundSolidColorWithRadius];
        // [self drawBackgroundWithGradience];
        // [self drawCircleWithColorFill];
        // [self drawCircleOverSquare];
        // [self drawMultiColorGradience];
        // [self drawObjectWithShadow];
        // [self drawRadialGradient];
        // [self drawChartGrid];
}

Drawing lines with different styles

-(void)drawDifferentLinesWithStyles
 {

[[NSColor blackColor] set];
 NSBezierPath *bPath = [NSBezierPath bezierPath];
 [bPath moveToPoint:NSMakePoint(50, 50)];
 [bPath lineToPoint:NSMakePoint(500, 50)];
 [bPath setLineWidth:5.0];
 [bPath stroke];

bPath = [NSBezierPath bezierPath];
 [bPath moveToPoint:NSMakePoint(50, 100)];
 [bPath lineToPoint:NSMakePoint(500, 100)];
 [bPath setLineWidth:15.0];
 [bPath stroke];

bPath = [NSBezierPath bezierPath];
 [bPath moveToPoint:NSMakePoint(50, 150)];
 [bPath lineToPoint:NSMakePoint(500, 150)];
 [bPath setLineWidth:15.0];
 [bPath setLineCapStyle:NSRoundLineCapStyle];
 [bPath stroke];

bPath = [NSBezierPath bezierPath];
 [bPath moveToPoint:NSMakePoint(50, 200)];
 [bPath lineToPoint:NSMakePoint(500, 200)];
 [bPath setLineWidth:15.0];
 [bPath stroke];

CGFloat lineDash[3];
 lineDash[0] = 30.0;
 lineDash[1] = 15.0;
 lineDash[2] = 5.0;
 bPath = [NSBezierPath bezierPath];
 [bPath moveToPoint:NSMakePoint(50, 250)];
 [bPath lineToPoint:NSMakePoint(500, 250)];
 [bPath setLineWidth:15.0];
 [bPath setLineDash:lineDash count:3 phase:0];
 [bPath stroke];
}

Cocoa_CoreGraphics_9


Drawing a Rectangle With Rounded Border and Solid Color

-(void)drawSquareBackgroundSolidColorWithRadius
{

[NSGraphicsContext saveGraphicsState];
[[NSColor darkGrayColor] setFill];
[[NSBezierPath bezierPathWithRoundedRect:[self bounds] xRadius:8.0 yRadius:8.0] fill];
[NSGraphicsContext restoreGraphicsState];

}

On Calling the above method from CustomView drawRect method

Cocoa_CG2


Drawing a Rectangle With Rounded Border and Gradient Color

-(void)drawBackgroundWithGradience
{

NSColor *startingColor;
NSColor *endingColor;
NSGradient* aGradient;
startingColor = [NSColor colorWithCalibratedRed:0.20 green:0.20 blue:0.25 alpha:1.0];
endingColor = [NSColor colorWithCalibratedRed:0.37 green:0.42 blue:0.49 alpha:1.0];
aGradient = [[NSGradient alloc]
initWithStartingColor:startingColor
endingColor:endingColor];
NSBezierPath *bezierPath = [NSBezierPath bezierPathWithRoundedRect:[self bounds] xRadius:8.0 yRadius:8.0];
[aGradient drawInBezierPath:bezierPath angle:270];

}
Cocoa_CG3


Drawing a Circle filled with Solid Color

-(void)drawCircleWithColorFill
{

NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:NSInsetRect([self bounds], 10,10)];
[[NSColor colorWithCalibratedRed:0.37 green:0.42 blue:0.49 alpha:1.0] set];
[path fill];
[[NSColor whiteColor] set];
[path setLineWidth:1.0];
[path stroke];

}
Cocoa_CG4


Drawing a Circle filled with Solid Color, inside a square

-(void)drawCircleOverSquare
{

//This is sample for multiple bezier path
[[NSColor orangeColor] set];
[[NSBezierPath bezierPathWithRect:self.bounds] fill];

NSBezierPath *path = [NSBezierPath bezierPathWithOvalInRect:NSInsetRect([self bounds], 30,30)];
[[NSColor redColor] set];
[path fill];
[[NSColor whiteColor] set];
[path setLineWidth:1.0];
[path stroke];

}
Cocoa_CG5


Drawing a rectangle with Multicolor gradience Fill

-(void)drawMultiColorGradience
{

NSRect bounds = [self bounds];
NSBezierPath* clipShape = [NSBezierPath bezierPath];
[clipShape appendBezierPathWithRoundedRect:bounds xRadius:40 yRadius:30];

NSGradient* aGradient = [[NSGradient alloc]
initWithColorsAndLocations:

[NSColor redColor], (CGFloat)0.0,
[NSColor orangeColor], (CGFloat)0.166,
[NSColor yellowColor], (CGFloat)0.33,
[NSColor greenColor], (CGFloat)0.5,
[NSColor blueColor], (CGFloat)0.75,
[NSColor purpleColor], (CGFloat)1.0,
nil];

[aGradient drawInBezierPath:clipShape angle:0.0];

}
Cocoa_CG6


Drawing an Object with Shadow

-(void)drawObjectWithShadow
{

//We are going to draw a square with Shadow
[NSGraphicsContext saveGraphicsState];

// Create the shadow below and to the right of the shape.
NSShadow* theShadow = [[NSShadow alloc] init];
[theShadow setShadowOffset:NSMakeSize(10.0, -10.0)];
[theShadow setShadowBlurRadius:4.0];

// Use a partially transparent color for shapes that overlap.
[theShadow setShadowColor:[[NSColor blackColor]
colorWithAlphaComponent:0.3]];

[theShadow set];

// Draw your custom content here. Anything you draw automatically has the shadow effect applied to it.

NSBezierPath *bPath = [NSBezierPath bezierPathWithRect:NSMakeRect(40,40, 200, 200)];
[[NSColor whiteColor] set];
[bPath fill];
[NSGraphicsContext restoreGraphicsState];

}
Cocoa_CG7


Drawing a Circle With Radial Gradience

- (void)drawRadialGradient
{

NSRect bounds = [self bounds];

NSGradient* aGradient = [[NSGradient alloc]
initWithStartingColor:[NSColor yellowColor]
endingColor:[NSColor redColor]];

NSPoint centerPoint = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
NSPoint otherPoint = NSMakePoint(centerPoint.x + 60.0, centerPoint.y + 60.0);
CGFloat firstRadius = MIN( ((bounds.size.width/2.0) - 2.0),
((bounds.size.height/2.0) -2.0) );
[aGradient drawFromCenter:centerPoint radius:firstRadius
toCenter:otherPoint radius:2.0
options:0];

}
Cocoa_CG8


Drawing a 5 * 5 Grid for Rendering Graphs and Charts.

Cocoa_CG1

//Drawing the Grid and Axis for a Charting Area
-(void)drawChartGrid
{

NSArray *sViews = [self subviews];

//The below code is for cleaning up the view for drawing

for (int j=0; j<[sViews count];)
{
[[sViews objectAtIndex:0] removeFromSuperview];
}

float axisXStart = 100;
float axisYStart = 100;
float gridXStart = 95;
float gridYStart = 95;

//Drawing the X-Axis and Y-Axis

NSBezierPath *path = [NSBezierPath bezierPath];
[path moveToPoint:[self originPoint]];
[path lineToPoint:NSMakePoint(axisXStart, [self axisMaxHeight])];
[[NSColor blackColor] set];
[path setLineWidth: 1.8];
[path stroke];
[path moveToPoint:[self originPoint]];
[path lineToPoint:NSMakePoint([self axisMaxWidth], axisYStart)];

//Horizontal Arrow
[path moveToPoint:NSMakePoint([self axisMaxWidth]-20, axisYStart-10)];
[path lineToPoint:NSMakePoint([self axisMaxWidth], axisYStart)];
[path lineToPoint:NSMakePoint([self axisMaxWidth]-20, axisYStart+10)];
[path stroke];

//Vertical Arrow
[path moveToPoint:NSMakePoint(axisXStart-10, [self axisMaxHeight]-20)];
[path lineToPoint:NSMakePoint(axisXStart, [self axisMaxHeight])];
[path lineToPoint:NSMakePoint(axisXStart+10, [self axisMaxHeight]-20)];
[path stroke];

//Drawing the Horizontal Grid With Labels
NSFont *font = [NSFont userFontOfSize:10];
int numOfSegments = 5;
float segmentWidth = ([self gridMaxWidth] - gridXStart)/numOfSegments;
NSBezierPath *hPath = [NSBezierPath bezierPath];
[[NSColor redColor] set];

CGFloat lineDash[2];
lineDash[0] = 10.0;
lineDash[1] = 5.0;

for (int i=1; i<=numOfSegments; i++)
{
[hPath moveToPoint:NSMakePoint(gridXStart + (i*segmentWidth), gridYStart)];
[hPath lineToPoint:NSMakePoint(gridXStart + (i*segmentWidth), [self gridMaxHeight])];
//[hPath setLineWidth: 1.2];
[hPath setLineDash:lineDash count:2 phase:1.0];
[hPath stroke];

NSTextField *tField = [[NSTextField alloc] initWithFrame:NSMakeRect(gridXStart + (i*segmentWidth), gridYStart-40, 50, 18)];
[tField setFont:font];
[tField setEditable:NO];
[tField setBordered:NO];
[tField setDrawsBackground:NO];
[tField setStringValue:[NSString stringWithFormat:@"Label %d",i]];
[tField setTextColor:[NSColor darkGrayColor]];
[tField setFrameRotation:90];
[self addSubview:tField];
}

//Drawing the Horizontal Grid With Labels
int numOfVerSegments = 5;
float segmentHeight = ([self gridMaxHeight] - gridYStart)/numOfVerSegments;

NSBezierPath *vPath = [NSBezierPath bezierPath];
[vPath setLineWidth: 0.2];

for (int i=1; i<=numOfVerSegments; i++)
{

[vPath moveToPoint:NSMakePoint(gridXStart , gridYStart+ (i*segmentHeight))];
[vPath lineToPoint:NSMakePoint([self gridMaxWidth], gridYStart + (i*segmentHeight))];
[vPath setLineDash:lineDash count:2 phase:1.0];
[vPath stroke];
NSTextField *tField = [[NSTextField alloc] initWithFrame:NSMakeRect(gridXStart - 80, gridYStart -10 + (i*segmentHeight), 80, 18)];
[tField setEditable:NO];
[tField setBordered:NO];
[tField setDrawsBackground:NO];
[tField setStringValue:[NSString stringWithFormat:@"Vert - Label %d",i]];

[tField setFont:font];
[tField setTextColor:[NSColor blackColor]];
[self addSubview:tField];

}

}

-(NSPoint) originPoint
{

NSPoint origin = NSMakePoint(100, 100);
return origin;

}

-(float)gridMaxHeight
{

float mHeight = [self frame].size.height - 60;
return mHeight;

}

-(float)axisMaxHeight
{

float mHeight = [self frame].size.height - 40;
return mHeight;

}

-(float)gridMaxWidth
{

float mWidth = [self frame].size.width - 100;
return mWidth;

}

-(float)axisMaxWidth
{

float mWidth = [self frame].size.width - 20;
return mWidth;

}

Another example of sample cocoa drawing is NSBezierPath Curves and Graphs


References
https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40003290-CH201-SW1

Posted in Cocoa, Objective C, Swift Tagged with: , , , , , ,
5 comments on “Drawing in Cocoa, Objective C using NSBezierPath
  1. velykovits@gmail.com says:

    Hi,

    I find your article very useful, but unfortunately I cannot even add the Cocoa framework if I choose my new project as a Game project.

    Do you know the trick?

    By the way I would like to compile it for iOS7 and by default it try to add only the iOS8 libraries that makes my app crash on an iOS7 device obviously.

    Thanks in advance.

    Kind regards,
    Zsolt

    • Debasis Das says:

      Hi Zsolt,

      In your Xcode proj, go to the target setting –> Build Phases and there you can add the frameworks.
      For making the environment as iOS7 go to the Target Setting–> Deployment Target and change it to ios7
      for project build setting set the SDK as iOS7 SDK and you should be all set.

      Let me know if you need further information on this.

  2. Agustin says:

    Will you be updating this information for iOS 8/swift? this information is amazing, except I just started learning swift and would greatly like some plotting/graphing info on swift coding.

    Thanks!

  3. Ivan says:

    Hello!
    Can i ask you about my problems with few objects in one path?
    If you can check it and help, it’s will be very great!! )))
    Thank you!
    http://stackoverflow.com/q/36675951/5310489

5 Pings/Trackbacks for "Drawing in Cocoa, Objective C using NSBezierPath"
  1. […] For further reading on Drawing using NSBezierPath also refer to Drawing in Cocoa, Objective C using NSBezierPath […]

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Recent Posts


Hit Counter provided by technology news