UIBezierPath で角の丸い多角形を作りたくて調べていたら三角形での例を見つけたので、多角形に応用するコードを書いてみました。
以下のコードは UIView
の draw(_:)
でこの三角形を描画する例です。UIBezierPath
の自作イニシャライザに多角形の頂点を渡しています。
class ShapeView: UIView {
override func draw(_ rect: CGRect) {
guard let ctx = UIGraphicsGetCurrentContext() else {
return
}
// 三角形の頂点座標を作成する
let radius: CGFloat = 25
let x: CGFloat = 25, y: CGFloat = 25
let pos1 = CGPoint(x: x + radius * cos(0), y: y + radius * sin(0))
let pos2 = CGPoint(x: x + radius * cos(2 / 6 * 2 * .pi), y: y + radius * sin(2 / 6 * 2 * .pi))
let pos3 = CGPoint(x: x + radius * cos(4 / 6 * 2 * .pi), y: y + radius * sin(4 / 6 * 2 * .pi))
// UIBezierPathの自作イニシャライザに頂点座標を渡す
// ratio(0.0~1.0)で丸さを調整できる
let path = UIBezierPath(roundedPolygon: [pos1, pos2, pos3], ratio: 0.5)
// パスが閉じていないので、close()で閉じる
path.close()
ctx.addPath(path.cgPath)
ctx.setLineWidth(4)
ctx.setStrokeColor(UIColor.red.cgColor)
ctx.strokePath()
}
}
UIBezierPath(roundedPolygon:ratio:)
の実装です。
extension UIBezierPath {
public convenience init(roundedPolygon points: [CGPoint], ratio: CGFloat) {
self.init()
for i in 0 ..< points.count {
var prev = i - 1
if prev < 0 {
prev = points.count - 1
}
var next = i + 1
if next >= points.count {
next = 0
}
let p1 = points[prev]
let p2 = points[i]
let p3 = points[next]
let p12 = CGPoint(
x: (p1.x + p2.x) / 2 * ratio + p2.x * (1 - ratio),
y: (p1.y + p2.y) / 2 * ratio + p2.y * (1 - ratio)
)
let p23 = CGPoint(
x: (p2.x + p3.x) / 2 * ratio + p2.x * (1 - ratio),
y: (p2.y + p3.y) / 2 * ratio + p2.y * (1 - ratio)
)
if self.isEmpty {
self.move(to: p12)
} else {
self.addLine(to: p12)
}
self.addQuadCurve(to: p23, controlPoint: p2)
}
}
}