見出し画像

SwiftUI Tutorials - Drawing Paths and Shapes-2

Draw the Badge Symbol

バッジの中身を作っていきます。ダウンロードしたResourcesからXcodeに取り込みます。

新しいSwiftUIファイルBadgeSymbol.swiftを作ります。

path APIsを使って図形を書きます。

        GeometryReader { geometry in
           Path { path in
               let width = min(geometry.size.width, geometry.size.height)
               let height = width * 0.75
               let spacing = width * 0.030
               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 * 3))
               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)
               ])

そして背景に色を付けます。

色については先に変数で定義しておき

 static let symbolColor = Color(red: 79.0 / 255, green: 79.0 / 255, blue: 191.0 / 255)

背景に適応します。

.fill(Self.symbolColor)

もう一つRotatedBadgeSymbol.swiftというSwiftUIファイルを作成し、構造体RotatedBadgeSymbolを作ります。

struct RotatedBadgeSymbol: View {
   let angle: Angle
   
   var body: some View {
       BadgeSymbol()
           .padding(-60)
           .rotationEffect(angle, anchor: .bottom)
   }
}

回転した図形としています。変数angleに数値を入れて回転の角度を指定します。

Combine the Badge Foreground and Background

今まで作ってきたバッジの背景とその中に入れる図形を合体させます。

Badge.swiftという名前で新しいSwiftUIファイルを作ります。そして作っておいた構造体を配置していきます。

var badgeSymbols: some View {
       RotatedBadgeSymbol(angle: Angle(degrees: 0))
           .opacity(0.5)
   }
   
var body: some View {
       ZStack {
           BadgeBackground()
           
           badgeSymbols
       }

ここでは

var badgeSymbols: some View {
RotatedBadgeSymbol(angle: Angle(degrees: 0))
.opacity(0.5)
}

として透過度を上げて透かした図形を作っておき、

var body: some View {}

にZStackを使って

GeometryReaderを使い画面の大きさを利用して

 GeometryReader { geometry in
               badgeSymbols
                   .scaleEffect(1.0 / 4.0, anchor: .top)
                   .position(x: geometry.size.width / 2.0, y: (3.0 / 4.0) * geometry.size.height)
           }

としています。

これで一つの図形が表示ができるようになったので、基本の形ができたのであとはループを使って8個配置するようにします。

まず変数で表示したい図形の数を指定します。

  static let rotationCount = 8

ループで回します。

  ForEach(0..<Badge.rotationCount) { i in
           RotatedBadgeSymbol(
               angle: .degrees(Double(i) / Double(Badge.rotationCount)) * 360.0
           )
       }
       .opacity(0.5)

そして図形を背景に合うように大きさを調整させます。

 .scaledToFit()

最後にこんな感じになります。

画像1


この記事が気に入ったらサポートをしてみませんか?