LoginSignup
1
3

More than 1 year has passed since last update.

この世でいちばんわかりやすいSwiftUIのパス描画

Last updated at Posted at 2021-06-19

この投稿は何?

SwiftUIフレームワーク上でパスを描画する方法を解説します。
下図のような「パイチャートなどを描画するために利用できる扇形」のパスを各コードを書いていきます。

スクリーンショット 2021-06-18 23.38.11.png

実行環境

macOS 11.4
Xcode 12.5
Swift 5.4

ハンズオン

ここで実践するシェイプは「パスの始まりと終わり」が閉じるまで、見ることはできません。
円弧を描けると、プレビュー上で確認することができます。

Shapeプロトコル

パスを描画するにはShapeプロトコルに適合した構造体を定義します。
一般的なSwiftUIビューのようなViewプロトコルでないので注意してください。

Pie構造体にShapeプロトコルを採用する
import SwiftUI

struct Pie: Shape {
    func path(in rect: CGRect) -> Path {
        // draw and return Path
    }
}

型にShapeプロトコルを採用すると、path(in:)メソッドの実装が要求されます。
このメソッドのボディで、描画したいパスを実装します。

パスのインスタンスを作成する

描画される線はPath型のインスタンスです。
とりあえず、パスのインスタンスを作成して、そのまま返しておきます。

path(in
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {        
        var path = Path()
        return path
    }
}

以降、作成したパスのインスタンスに対して、「どのような図形を描画するか」を指定していきます。

パスの始まりを決める

画面の中央となる点を取得します。
path(in:)メソッドが受け取るrectパラメータが、そのパスが描画される画面の情報を持っています。

path(in
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {        
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()
        return path
    }
}

画面の中央点がわかったら、そこを「パスの開始位置」とします。

ペンを中心に移動する
struct Pie: Shape {
    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)

        var path = Path()
        path.move(to: center)
        return path
    }
}

move(to:)メソッドで、パスのインスタンスを移動します。

直線を引く

パイの円弧が「開始される点」まで、直線を引きましょう。
パイの半径は「画面幅の半分」とします。
また、円弧の開始点は「画面の中心からX軸方向に半径分だけ移動した地点」とします。

直線を引く
struct Pie: Shape {    
    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = rect.width / 2
        let startPoint = CGPoint(
            x: center.x + radius,
            y: center.y
        )

        var path = Path()
        path.move(to: center)
        path.addLine(to: startPoint)
        return path
    }
}

円弧を引く

addArc(center:radius:startAngle:endAngle:clockwise)メソッドを使って、円弧を引くことができます。
5つのパラメータにはそれぞれ、以下の値を指定します。

  • 円弧の中心点
  • 円弧の半径
  • 円弧の開始角
  • 円弧の終了角
  • 円弧の進む方向
Pie
import SwiftUI

struct Pie: Shape {
    let startAngle = Angle(degrees: 0)
    let endAngle   = Angle(degrees: 90)

    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = rect.width / 2
        let startPoint = CGPoint(
            x: center.x + radius,
            y: center.y
        )

        var path = Path()
        path.move(to: center)
        path.addLine(to: startPoint)
        path.addArc(center: center,
                    radius: radius,
                    startAngle: startAngle,
                    endAngle:   endAngle,
                    clockwise: false
        )
        return path
    }
}

円弧の向きを調整するには、パス全体の角度を変更します。

struct Pie: Shape {
    let startAngle = Angle(degrees: 0-90)
    let endAngle   = Angle(degrees: 90-90)

    func path(in rect: CGRect) -> Path {
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = rect.width / 2
        let startPoint = CGPoint(
            x: center.x + radius * CGFloat(cos(startAngle.radians)),
            y: center.y + radius * CGFloat(sin(startAngle.radians))
        )

        var path = Path()
        path.move(to: center)
        path.addLine(to: startPoint)
        path.addArc(center: center,
                    radius: radius,
                    startAngle: startAngle,
                    endAngle:   endAngle,
                    clockwise: false
        )
        return path
    }
}

スクリーンショット 2021-06-19 16.48.21.png

三角関数については、こちらのnoteで説明しています。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3