Drawing Shapes with Core Graphics Tutorial

Core Graphics is an API included in both Cocoa and Cocoa Touch. It allows you to draw graphic objects on the graphic destination. In this tutorial we will draw some basic shapes such as a rectangle or a circle. This tutorial is made with Xcode 8 and built for iOS 10.

Open Xcode and create a new Single View Application.

Choose Next. For product name, use IOS10DrawShapesTutorial and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and make sure only iPhone is selected in Devices.

Go to the Storyboard and drag a Horizontal Stack View from the Object Library to the top section of the main View. Go to the Attributes inspector and in the Stack View section and change the Distributon type to Fill Equally. Drag 3 buttons from the Object Library to the Stack View and give them the following names: Rectangle, Lines and Circle. Select the Stack View and Select the Pin button from the Auto Layout button on the bottom-right of the Storyboard and fill in the following values. Select Add 3 Constraints.

The Storyboard will look like this.

Select each button and go to the Attributes Inspector. In the View section give the button from left to right a tag of 0,1 and 2. The tag field is needed later on so we will know which button is pressed.

Open The Assistant Editor and make sure the ViewController.swift file is visible. Ctrl And Drag from the "Lines" button to the ViewController class and create the following Action

Select the other buttons and Ctrl and drag to the IBAction method inside the ViewController class. Pressing each button will execute the IBAction method.

The drawing will take place inside a custom View. Add a New File to the project. Choose File -> New File -> iOS -> Cocoa Touch Class. Name the class ShapeView and make it a subclass of UIView.

Go to the ShapeView.swift file and add the following property.

var currentShapeType: Int = 0

The currentShapeType property is used to choose the right method to draw the corresponding object. Next add the following init methods

init(frame: CGRect, shape: Int) {
    super.init(frame: frame)
    self.currentShapeType = shape
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

When the custom view is initialised, the tag field is given which determines the shape type. the drawRect method is where the custom drawing takes place.

override func draw(_ rect: CGRect) {
    switch currentShapeType {
      case 0: drawRectangle()
      case 1: drawLines()
      case 2: drawCircle()
      default: print("default")
    }
}

Next, implement the drawing methods

func drawLines() {
    //1
    guard let ctx = UIGraphicsGetCurrentContext() else { return }
            
    //2
    ctx.beginPath()
    ctx.move(to: CGPoint(x: 20.0, y: 20.0))
    ctx.addLine(to: CGPoint(x: 250.0, y: 100.0))
    ctx.addLine(to: CGPoint(x: 100.0, y: 200.0))
    ctx.setLineWidth(5)
            
    //3
    ctx.closePath()
    ctx.strokePath()
}
        
func drawRectangle() {
    let center = CGPoint(x: self.frame.size.width / 2.0, y: self.frame.size.height / 2.0)
    let rectangleWidth:CGFloat = 100.0
    let rectangleHeight:CGFloat = 100.0
            
    guard let ctx = UIGraphicsGetCurrentContext() else { return }
            
    //4
    ctx.addRect(CGRect(x: center.x - (0.5 * rectangleWidth), y: center.y - (0.5 * rectangleHeight), width: rectangleWidth, height: rectangleHeight))
    ctx.setLineWidth(10)
    ctx.setStrokeColor(UIColor.gray.cgColor)
    ctx.strokePath()
            
    //5
    ctx.setFillColor(UIColor.green.cgColor)
            
    ctx.addRect(CGRect(x: center.x - (0.5 * rectangleWidth), y: center.y - (0.5 * rectangleHeight), width: rectangleWidth, height: rectangleHeight))
            
    ctx.fillPath()
}
        
func drawCircle() {
    let center = CGPoint(x: self.frame.size.width / 2.0, y: self.frame.size.height / 2.0);
            
    guard let ctx = UIGraphicsGetCurrentContext() else { return }
            ctx.beginPath()
            
    //6
    ctx.setLineWidth(5)
            
    let x:CGFloat = center.x
    let y:CGFloat = center.y
    let radius: CGFloat = 100.0
    let endAngle: CGFloat = CGFloat(2 * M_PI)
            
    ctx.addArc(center: CGPoint(x: x,y: y), radius: radius, startAngle: 0, endAngle: endAngle, clockwise: true)
            
    ctx.strokePath()
}
  1. The Graphic Context is your graphic destination. If you want to draw on a view, the view is your Graphic Context. We need to get a reference  to the Graphics Context.
  2. A path is a set of lines, arcs and curves you can draw on the current graphic context to build complex objects. Here we draw some lines and set the line width to 5.
  3. The path is closed and drawn to the graphics context.
  4. With CGContextAddRect a rectangle is drawn. the outline stroke color is gray.
  5. Here the same rectangle is defined, with a fill color of green
  6. With CGContextAddArc a circle is drawn

 Next, implement the buttonPressed method in the ViewController.swift file

@IBAction func buttonPressed(_ sender: AnyObject) {
    let myView = ShapeView(frame: CGRect(x: 25, y: 200, width: 280, height: 250), shape: sender.tag)
    myView.backgroundColor = UIColor.cyan
    view.addSubview(myView)
}

Build and Run and click on each button to draw the different shapes.

You can download the source code of the IOS10DrawShapesTutorial at the ioscreator repository on Github.