CoreGraphics の使い方を初心者向けに書いてみた – Swift3.0

備忘録として、雑ですみません。一番下にgithubあげておきます。もしよければ動かしてみてください。CoreGraphics自体は非常に安易に動きます。

CoreGraphicsとは

Core GraphicsはAppleのベクトル描画フレームワークです。これは大きくて強力なAPIであり、学ぶべきことがたくさんあります。しかし、決して恐れることはありません。

新しいプロジェクトの作成

新しいプロジェクトの作成していきましょう。ビューにグラフィックスを描画するには、UIViewオブジェクトのサブクラスを作成し、drawメソッドをオーバーライドする必要があります。

viewのクラスを定義する

スクリーンショット 2017-05-04 13.34.03.png
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


//UIViewを継承したDraw2Dを定義する
//別のファイルに書いても構わない
//ここでは簡易的にclass ViewControllerの下に直接新しいクラスを書いてしまった

class Draw2D: UIView {

    override func draw(_ rect: CGRect) {

    //ここにコードを書いていく


    }
}   

ラインを描く

Quartz 2Dを使用してデバイス画面に線を描画するには、最初にビューのグラフィックスコンテキストを取得する必要があります。

let context = UIGraphicsGetCurrentContext()

コンテキストが取得されたら、描画する線の幅を指定する必要があります。

context?.setLineWidth(2.0)

次に、カラーリファレンスを作成する必要があります。必要な色(この場合は不透明な青色)のRGBAコンポーネントを指定することで、これを行うことができます。

let colorSpace = CGColorSpaceCreateDeviceRGB()
let components: [CGFloat] = [0.0, 0.0, 1.0, 1.0]
let color = CGColor(colorSpace: colorSpace, components: components)

カラーリファレンスとコンテキストを使用して、ラインを描画するときにカラーを使用するように指定できるようになりました:

context?.setStrokeColor(color!)

次のステップは、描画される線の始点に移動することです:

context?.move(to: CGPoint(x: 30, y: 30))

上記のコード行は、行の開始点がデバイスのディスプレイの左上隅であることを示します。ここでは線の終点を指定する必要があります。この場合は300,400です。

context?.addLine(to: CGPoint(x: 300, y: 400))

線幅、色、およびパスを定義したら、線を描画する準備が整いました。

context?.strokePath()

 実行

スクリーンショット 2017-05-04 14.41.31.png

全ソース

スクリーンショット 2017-05-04 14.42.38.png
//
//  ViewController.swift
//  Swift3CoreGraphicsSample
//
//  Created by ryosuke-hujisawa on 2017/05/04.
//  Copyright © 2017年 ryosuke-hujisawa. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


class Draw2D: UIView {

    override func draw(_ rect: CGRect) {
        // Drawing code

        //コンテキストを取得
        let context = UIGraphicsGetCurrentContext()

        //幅
        context?.setLineWidth(2.0)

        //RGBAコンポーネントを指定
        let colorSpace = CGColorSpaceCreateDeviceRGB()

        //必要性が謎
        let components: [CGFloat] = [0.0, 0.0, 1.0, 1.0]

        //カラーを指定
        let color = CGColor(colorSpace: colorSpace, components: components)

        //カラーを描画
        context?.setStrokeColor(color!)

        //描画される線の始点に移動する
        context?.move(to: CGPoint(x: 30, y: 30))

        //線の終点を指定
        context?.addLine(to: CGPoint(x: 300, y: 400))

        //準備完了
        context?.strokePath()





    }
}   

上記の例では、色空間と色の参照を手動で作成したことに注意してください。 Drawing iOS 10で説明されているように、Core Graphicsカラーを使用した2Dグラフィックスは、UIColorクラスを使用して作成することもできます。たとえば、次のようにコードの行数を減らして、上で概説したのと同じ結果を得ることができます。

class Draw2D: UIView {

    override func draw(_ rect: CGRect) {
        // Drawing code

        let context = UIGraphicsGetCurrentContext()
        context?.setLineWidth(2.0)
        context?.setStrokeColor(UIColor.blue.cgColor)
        context?.move(to: CGPoint(x: 30, y: 30))
        context?.addLine(to: CGPoint(x: 300, y: 400))
        context?.strokePath()

    }
}   

描画パス

上の例では、2つの点の間のパスを本質的に定義することによって、1つの線を描画しています。複数の点を含むパスを定義することで、コンテキストのaddLine(to :)メソッドを繰り返し呼び出すことによって、すべて互いに接続された一連の直線を使用して描画することができます。非直線は、例えばaddArcメソッドの呼び出しを使用してシェイプに追加することもできます。
たとえば、次のコードは菱形を描画します。

override func draw(_ rect: CGRect)
{
    let context = UIGraphicsGetCurrentContext()
    context?.setLineWidth(2.0)
    context?.setStrokeColor(UIColor.blue.cgColor)
    context?.move(to: CGPoint(x:100, y: 100))
    context?.addLine(to: CGPoint(x: 150, y: 150))
    context?.addLine(to: CGPoint(x: 100, y: 200))
    context?.addLine(to: CGPoint(x: 50, y: 150))
    context?.addLine(to: CGPoint(x: 100, y: 100))
    context?.strokePath()
}
スクリーンショット 2017-05-04 14.46.12.png

長方形の描画

四角形の左上隅のx座標とy座標を矩形の高さと幅とともに指定することによってパスが定義されることを除いて、長方形は他のパスと同じように描画されます。これらの次元はCGRect構造体に格納され、引数としてaddRectメソッドに渡されます。

描画勾配

グラデーションは、線形、放射状、軸方向のグラデーションをサポートするCore Graphics CGGradientクラスを使用して実装されています。 CGGradientクラスの使用には、基本的に2つ以上の色の指定と1組の位置値が含まれます。位置値は、グラデーションが軸線に沿って描画されるときに、グラデーションがある色から別の色に切り替わる点を示すために使用され、0.0は軸の始点を表し、1.0は終点を表します。たとえば、グラデーションを作成して、3つの異なる色をグラデーション軸に沿って移動させ、各色にグラデーション内の同量のスペースが与えられているとします。この場合、3つの場所が指定されます。最初はグラデーションの開始を表す0.0になります。その後、残りの色への遷移点に2つの場所を指定する必要があります。色の間で軸を均等に分割するには、それぞれ0.3333と0.6666に設定する必要があります。CGGradientインスタンスを設定すると、線形グラデーションがコンテキストオブジェクトのdrawLinearGradientメソッドへの呼び出しによって描画され、色、位置、開始点と終了点を引数として渡します。たとえば、次のコードでは、4つの等間隔の位置に4色を使用して直線勾配を描きます。

override func draw(_ rect: CGRect)
{
    let context = UIGraphicsGetCurrentContext()

    let locations: [CGFloat] = [ 0.0, 0.25, 0.5, 0.75 ]

    let colors = [UIColor.red.cgColor,
                  UIColor.green.cgColor,
                  UIColor.blue.cgColor,
                  UIColor.yellow.cgColor]

    let colorspace = CGColorSpaceCreateDeviceRGB()

    let gradient = CGGradient(colorsSpace: colorspace,
                  colors: colors as CFArray, locations: locations)

    var startPoint = CGPoint()
    var endPoint =  CGPoint()

    startPoint.x = 0.0
    startPoint.y = 0.0
    endPoint.x = 600
    endPoint.y = 600

    context?.drawLinearGradient(gradient!,
               start: startPoint, end: endPoint, 
            options: .drawsBeforeStartLocation)
}  
スクリーンショット 2017-05-04 15.01.33.png

まる

 let context = UIGraphicsGetCurrentContext()
        let locations: [CGFloat] = [0.0, 1.0]

        let colors = [UIColor.white.cgColor,
                      UIColor.blue.cgColor]

        let colorspace = CGColorSpaceCreateDeviceRGB()

        let gradient = CGGradient(colorsSpace: colorspace,
                                  colors: colors as CFArray, locations: locations)

        var startPoint = CGPoint()
        var endPoint = CGPoint()
        startPoint.x = 180
        startPoint.y = 180
        endPoint.x = 200
        endPoint.y = 200
        let startRadius: CGFloat = 0
        let endRadius: CGFloat = 75

        context?.drawRadialGradient (gradient!, startCenter: startPoint,
                                     startRadius: startRadius, endCenter: endPoint,
                                     endRadius: endRadius,
                                     options: .drawsBeforeStartLocation)
スクリーンショット 2017-05-04 15.03.13.png

ラッパ

let context = UIGraphicsGetCurrentContext()

        let locations: [CGFloat] = [0.0, 0.5, 1.0]

        let colors = [UIColor.red.cgColor,
                      UIColor.green.cgColor,
                      UIColor.cyan.cgColor]

        let colorspace = CGColorSpaceCreateDeviceRGB()

        let gradient = CGGradient(colorsSpace: colorspace,
                                  colors: colors as CFArray, locations: locations)

        var startPoint =  CGPoint()
        var endPoint  = CGPoint()

        startPoint.x = 100
        startPoint.y = 100
        endPoint.x = 200
        endPoint.y = 200
        let startRadius: CGFloat = 10
        let endRadius: CGFloat = 75

        context?.drawRadialGradient(gradient!, startCenter: startPoint,
                                    startRadius: startRadius, endCenter: endPoint,
        endRadius: endRadius, options: [])
スクリーンショット 2017-05-04 15.04.43.png

参考

Core Graphics Tutorial Part 1: Getting Started

github

github

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事