🚀

【Drawing Paths and Shapes編】初心者がswiftUIチュートリアルをやって疑問に思ったことを調査して記していく

2023/09/19に公開

はじめに

図形描画のチュートリアルをやったので、その中で新しく出てきたものについて調査したので記していく。

図形を描画するファイルと図形情報の配列ファイルの二つがあるが、先に図形描画ファイルで出てきた新しい用語を確認した後に、図形情報の配列を見る。

CGPoint と CGFloat

CGPoint
2次元座標の点(x,y)を含む構造
引用 : CGPoint

CGFloat
Graphics (または、その関連フレームワーク)で使用される浮動小数点数

このタイプのサイズと精度は、CPU アーキテクチャによって異なります。64 ビット CPU 用にビルドする場合、CGFloat型は 64 ビットの IEEE 倍精度浮動小数点型であり、Double型と同等です。32 ビット CPU 用にビルドする場合、CGFloat型は 32 ビットの IEEE 単精度浮動小数点型であり、Float型と同等です。
引用 : CGFloat

GeometryReader とは

A container view that defines its content as a function of its own size and coordinate space.

コンテンツを独自のサイズと座標空間の関数として定義するコンテナービュー。
引用 : GeometryReader

その構造体をもつコンテンツのサイズや座標を関数から取得できるようになる。らしい。
ふ〜〜〜ん、便利やん

関数は主に
size : Viewのサイズ取得
frame : Viewの位置を取得
の2つ。

Path とは

The outline of a 2D shape.

2D図形の為のまとまり
引用 : Path
めっさシンプルな説明

クロージャ内で、関数から色んな図形を描けるってことやな。

今回使用した関数ども
move : パスの開始地点を指定する。
addLine : 現在いる地点から指定した地点まで直線を引く。
addQuadCurve : 現在いる地点から to引数 に指定した地点まで、control引数 に指定した地点を経由した曲線を引く。

BadgeBackground.swiftのコードを確認

公式内のコード
import SwiftUI

struct BadgeBackground: View {
    var body: some View {
        GeometryReader { geometry in
            Path { path in
	        //ここでViewの横幅か縦幅の小さい方を取得
                var width: CGFloat = min(geometry.size.width,
		                         geometry.size.height)
                let height = width
                let xScale: CGFloat = 0.832
		//左右にある空白の幅
                let xOffset = (width * (1.0 - xScale)) / 2.0
                width *= xScale
		//開始地点を指定(今回は、終点でもある)
                path.move(
                    to: CGPoint(
		        //segmentsの最後のcurveと一緒
                        x: width * 0.95 + xOffset,
                        y: height * (0.20 + 
			             HexagonParameters.adjustment)
                    )
                )

                //segments各要素を描画
                HexagonParameters.segments.forEach { segment in
		    //現在地から指定座標まで線を引く
                    path.addLine(
                        to: CGPoint(
                            x: width * segment.line.x + xOffset,
                            y: height * segment.line.y
                        )
                    )

                    //曲線を引く
                    path.addQuadCurve(
		        //最終地点
                        to: CGPoint(
                            x: width * segment.curve.x + xOffset,
                            y: height * segment.curve.y
                        ),
			//経由地点
                        control: CGPoint(
                            x: width * segment.control.x + xOffset,
                            y: height * segment.control.y
                        )
                    )
                }
            }
            .fill(.linearGradient(
                Gradient(colors: [Self.gradientStart, Self.gradientEnd]),
                startPoint: UnitPoint(x: 0.5, y: 0),
                endPoint: UnitPoint(x: 0.5, y: 0.6)
            ))
        }
        .aspectRatio(1, contentMode: .fit)
    }
    static let gradientStart = Color(red: 239.0 / 255, green: 120.0 / 255, blue: 221.0 / 255)

segments配列の各CGPointの意味

これまでの説明を踏まえて見てみると意外と単純なことがわかりますね。


わかりやすくするために、adjustmentは省いています。

まとめ

シンプルに記述できますが、故に複雑な図形を簡単に描画できるので、色々な応用ができそうですね。

Discussion