CoreGraphics でパスを回転する方法をメモ。

このメモでは半円を描画して90度回転する。

目次

  1. 検証環境
  2. 回転する処理をどこに追加するか
  3. 回転する処理
  4. サンプル

検証環境

  • macOS 10.12.5
  • Xcode 8.3.2
  • Swift 3.1

回転処理をどこに追加するか

基本的な描画フロー で例えると『2. パスを追加する』の『2. パスの追加』の前に回転する処理を追加する。

guard let context = UIGraphicsGetCurrentContext() else { return }
let center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)

// ここ

context.beginPath()
context.move(to: center)
context.addArc(center: center, radius: quarter, startAngle: startAngle, endAngle: endAngle, clockwise: false)

回転する処理

rotate(by:) を使用する。ただしこれだけだと正しく回転しない。

// 90度回転する
context.rotate(by: (90.0 * CGFloat.pi / 180.0))
context.beginPath()

we need to translate the context back to its original place

Saving a rotated image with CGContextRotateCTM | Treehouse Community

中心点が {0, 0} なので、translateBy(x:y:) を使用して中心点を移動する。

// 中心点を移動する
context.translateBy(x: center.x, y: center.y)
// 90度回転する
context.rotate(by: (90.0 * CGFloat.pi / 180.0))
// 中心点を元に戻す
context.translateBy(x: -center.x, y: -center.y)
context.beginPath()

回転した後に中心点を元に戻してからパスを追加する必要がある。

サンプル

override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }

    let lineWidth: CGFloat = 1.0
    let diameter = min(self.bounds.width, self.bounds.height) - lineWidth * 2 + lineWidth
    let radius = diameter / 2
    let center = CGPoint(x: self.bounds.width / 2, y: self.bounds.height / 2)
    let startAngle = -90.0 * CGFloat.pi / 180.0
    let endAngle = startAngle + CGFloat.pi

    context.translateBy(x: center.x, y: center.y)
    context.rotate(by: (90 * CGFloat.pi / 180.0))
    context.translateBy(x: -center.x, y: -center.y)

    context.beginPath()
    context.move(to: center)
    context.addArc(center: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false)
    context.closePath()

    context.setLineWidth(lineWidth)
    context.setStrokeColor(UIColor.black.cgColor)
    context.setFillColor(UIColor.gray.cgColor)
    context.drawPath(using: .fillStroke)
}

Next PostPrevious Post