Swift CGPathにCGAffineTransformを適用し変形する

tail -f my tech life.
5 min readNov 11, 2017

--

SwiftでCGPathをちょっと大きいくしたいなどの場合、CGPath自体を大きくする方法。 CGPathのcopyメソッドにCGAffineTransformを渡して任意の変形を行うことができる。

Creates an immutable copy of a graphics path transformed by a transformation matrix.

copy(using:) — CGPath | Apple Developer Documentation

func copy(using transform: UnsafePointer<CGAffineTransform>?) -> CGPath?

引数に CGAffineTransform のポインタを渡せば良いようだ。例えば、これで1.2倍サイズに変形できる。

var scale = CGAffineTransform(scaleX: 1.2 ,y: 1.2)
let transPath = path.copy(using: &scale)

CGAffineTransformの変数はvarで宣言する。letだと note: change ‘let’ to ‘var’ to make it mutableと 警告される。&でポインタ渡しだからかな?

青い図形が変換前、赤いほうが変換後。1.2倍の大きさになっている。

サンプルコード

func addPathLayer(){

// create path.
let path = CGMutablePath()
path.move(to: CGPoint(x:19.098,y:100))
path.addLine(to: CGPoint(x:25,y:63.82))
path.addLine(to: CGPoint(x:-0,y:38.197))
path.addLine(to: CGPoint(x:34.549,y:32.918))
path.addLine(to: CGPoint(x:50,y:-0))
path.addLine(to: CGPoint(x:65.451,y:32.918))
path.addLine(to: CGPoint(x:100,y:38.197))
path.addLine(to: CGPoint(x:75,y:63.82))
path.addLine(to: CGPoint(x:80.902,y:100))
path.addLine(to: CGPoint(x:50,y:82.918))
path.closeSubpath()

// copy path with transform
var scale = CGAffineTransform(scaleX: 1.2 ,y: 1.2)
let transPath = path.copy(using: &scale)

// show path on layer
let pathLayer = CAShapeLayer()
pathLayer.frame = view.bounds
pathLayer.path = path
pathLayer.strokeColor = UIColor.blue.cgColor
pathLayer.lineWidth = 2
pathLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(pathLayer)

let transpathLayer = CAShapeLayer()
transpathLayer.frame = view.bounds
transpathLayer.path = transPath
transpathLayer.strokeColor = UIColor.red.cgColor
transpathLayer.lineWidth = 2
transpathLayer.fillColor = UIColor.clear.cgColor
view.layer.addSublayer(transpathLayer)
}

参考

以前はCGPathCreateCopyByTransformingPathを使う方法だったようだが、Xcodeがこちらを使えというので使ってみた。

参考

--

--

tail -f my tech life.

iOSアプリを作っている、とある技術者のブログです。SwiftやiOS話題多いです。