
線と図形描画 – Drawing paths and shapes
section 1 バッヂビューで描画データ生成 Create drawing data for a badge view
File > New > File Swift File作成 – HexagonParameters.swift.
六角形のstruct作成
segment 区分、部分? struct
import CoreGraphics
struct HexagonParameters {
struct Segment {
let line : CGPoint
let curve : CGPoint
let control : CGPoint
}
// 調整
static let adjustment : CGFloat = 0.085
// 状態保持
static let segments = [
Segment(
line: CGPoint(x: 0.60, y: 0.05),
curve: CGPoint(x: 0.40, y: 0.05),
control: CGPoint(x: 0.50, y: 0.00)
),
Segment(
line: CGPoint(x: 0.05, y: 0.20 + adjustment),
curve: CGPoint(x: 0.00, y: 0.30 + adjustment),
control: CGPoint(x: 0.00, y: 0.25 + adjustment)
),
Segment(
line: CGPoint(x: 0.00, y: 0.70 - adjustment),
curve: CGPoint(x: 0.05, y: 0.80 - adjustment),
control: CGPoint(x: 0.00, y: 0.75 - adjustment)
),
Segment(
line: CGPoint(x: 0.40, y: 0.95),
curve: CGPoint(x: 0.60, y: 0.95),
control: CGPoint(x: 0.50, y: 1.00)
),
Segment(
line: CGPoint(x: 0.95, y: 0.80 - adjustment),
curve: CGPoint(x: 1.00, y: 0.70 - adjustment),
control: CGPoint(x: 1.00, y: 0.75 - adjustment)
),
Segment(
line: CGPoint(x: 1.00, y: 0.30 + adjustment),
curve: CGPoint(x: 0.95, y: 0.20 + adjustment),
control: CGPoint(x: 1.00, y: 0.25 + adjustment)
)
]
}六角形の頂点データですが、とりあえずという感じですね^^;
section 2 バッヂの背景描画
SwiftUI View を作成 BadgeBackground.swift
import SwiftUI
struct BadgeBackground: View {
var body: some View {
Path {
path in
var width: CGFloat = 100.0
let height = width
path.move(to: CGPoint(
x: width * 0.95,
y: height * 0.20
))
HexagonParameters.segments.forEach{
segment in
path.addLine(to: CGPoint(
x:width * segment.line.x,
y:height * segment.line.y
))
}
}
.fill(.black)
}
}
#Preview {
BadgeBackground()
}
Pathって線っぽいイメージですが、道筋、軌道、「軌道」は線に方向があるイメージですね
100×100の中で、x, y,を順に頂点をつけて、七角形?が出来ているようです

addQuadCurve(to:control:) で Quadは四角形でしょうか?QuadCurve…
Appends a quadratic Bézier curve to the path. ベジェ曲線をパスに追加と
これだけだと右上が少しズレていて
最初の点に
y: height * (0.20 + HexagonParameters.adjustment)
とすると綺麗に揃いました…んーなかなか
イマイチピンときませんがとりあえず進めます^^
GeometryReader で geometry を使って 100指定していたサイズを画面の縦横の小さい方に設定されたようです

横幅を調整したようです
色グラデーションを付けたようです、中央へ

section 3 バッヂシンボル描画
サンプルプロジェクトファイルにある
Resources / landmark_app_icon_1024x1024.pngをAssets catalog の AppIconのところに入れる

SwiftUI View : BadgeSymbol.swift を生成
山の形を作るらしい
こちらはシンプルな描画なのでわかりやすいですね
struct BadgeSymbol: View {
static let symbolColor = Color(red:79.0/255,green:79.0/255,blue:191.0/255)
var body: some View {
GeometryReader{
geometry in
Path { path in
let width = min(geometry.size.width, geometry.size.height)
let height = width * 0.75
let spacing = width * 0.03
let middle = width * 0.5
let topWidth = width * 0.226
let topHeight = height * 0.488
path.addLines([
CGPoint(x:middle, y:spacing),
CGPoint(x:middle - topWidth, y:topHeight - spacing),
CGPoint(x:middle, y:topHeight/2 + spacing),
CGPoint(x:middle+topWidth, y: topHeight - spacing),
CGPoint(x: middle, y: spacing)
])
path.move(to: CGPoint(x:middle, y: topHeight/2 + spacing))
path.addLines([
CGPoint(x: middle - topWidth, y:topHeight + spacing),
CGPoint(x:spacing, y: height - spacing),
CGPoint(x:width - spacing, y: height - spacing),
CGPoint(x: middle + topWidth, y:topHeight + spacing),
CGPoint(x: middle, y: topHeight/2 + spacing*3)
])
}
.fill(Self.symbolColor)
}
}
}SwiftUI View : RotatedBadgeSymbol.swift を作成し、傾ける
struct RotatedBadgeSymbol: View {
let angle: Angle
var body: some View {
BadgeSymbol()
.padding(-60)
.rotationEffect(angle, anchor:.bottom)
}
}
#Preview {
RotatedBadgeSymbol(angle: Angle(degrees:5))
}section 4 バッジの前景と背景をあわせる
foregroundって前景だけどなんか前景って馴染みないですね
SwiftUI View : Badge.swiftを作成

単純に、zstack で BadgeBackgroundとBadgeSymbolを重ねるとこんな感じ
BadgeSymbolをいくつか変形
角度を変更して8つ並べる

こんな感じで出来ました。
難しくはないけど、これ作ろう!と思ってこの手順で進めるのは慣れないと
Check Your Understanding
英語難しい^^;
グラフなど描画するのに使う感じですかね?



コメント