🍏

GitHub Copilot for Xcode Chatで何か作る①

2025/02/18に公開

Note(ノート)

GitHub Copilot for Xcode Chatを使用してどれほどのものが作れるのか最近実験をしてみようと思いました。指示を出すと英語で回答されるのですが、日本語の指示は理解できるみたい。

第1弾はアナログ時計を作ってみようと思います。プロンプトのスクショ忘れた😅

これが時計

全体のコード

人間が思いつかないロジックをすぐに書いてくれた😅
見た目はシンプルですがいい感じに動いていた。

import SwiftUI

struct ContentView: View {
    var body: some View {
        ClockView()
    }
}

struct ClockView: View {
    @State private var currentTime = Time()

    var body: some View {
        ZStack {
            Circle()
                .stroke(lineWidth: 2)
                .foregroundColor(.black)
                .frame(width: 200, height: 200)

            ForEach(0..<12) { tick in
                Rectangle()
                    .fill(Color.black)
                    .frame(width: 2, height: tick % 3 == 0 ? 15 : 7)
                    .offset(y: -100)
                    .rotationEffect(.degrees(Double(tick) * 30))
            }

            HandView(length: 80, thickness: 4, angle: .degrees(currentTime.hoursAngle))
            HandView(length: 90, thickness: 2, angle: .degrees(currentTime.minutesAngle))
            HandView(length: 100, thickness: 1, angle: .degrees(currentTime.secondsAngle))
        }
        .onAppear(perform: updateTime)
    }

    private func updateTime() {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
            self.currentTime = Time()
        }
    }
}

struct HandView: View {
    var length: CGFloat
    var thickness: CGFloat
    var angle: Angle

    var body: some View {
        Rectangle()
            .fill(Color.black)
            .frame(width: thickness, height: length)
            .offset(y: -length / 2)
            .rotationEffect(angle)
    }
}

struct Time {
    private var date = Date()
    private var calendar = Calendar.current

    var hours: Int {
        calendar.component(.hour, from: date) % 12
    }

    var minutes: Int {
        calendar.component(.minute, from: date)
    }

    var seconds: Int {
        calendar.component(.second, from: date)
    }

    var hoursAngle: Double {
        Double(hours) * 30 + Double(minutes) / 2
    }

    var minutesAngle: Double {
        Double(minutes) * 6
    }

    var secondsAngle: Double {
        Double(seconds) * 6
    }
}

#Preview {
    ClockView()
}

#Preview {
    ContentView()
}

Que(きっかけ)

GitHub Copilot for Xcode Chatが使えるようになり世の中の人が注目していたので試してみた。
https://zenn.dev/joo_hashi/articles/52ef04563f0728

Summary(要約)

では、このアナログ時計を実装したSwiftUIコードについて解説させていただきます。

アナログ時計の実装解説

このコードはSwiftUIを使用してシンプルなアナログ時計を実装しています。時計の文字盤、時針、分針、秒針をすべてSwiftUIの基本的な図形を組み合わせて表現し、実際の時間に合わせて動作します。

全体の構造

コードは主に4つの構造体で構成されています:

  1. ContentView - アプリケーションのメインビュー
  2. ClockView - 時計の表示を担当する中心的なビュー
  3. HandView - 時計の針を表現するためのビュー
  4. Time - 現在時刻の計算を行うモデル

ClockViewの実装

ClockViewは時計の外観と動作を制御する中心的なコンポーネントです。以下の要素で構成されています:

  • 外周の円:Circle()を使用して時計の外枠を描画
  • 目盛り:ForEachループを使用して12個の目盛りを配置。3の倍数の位置では長い目盛りを表示
  • 3種類の針:時針、分針、秒針をそれぞれ異なる長さと太さで表現
  • タイマー:onAppearTimerを使用して1秒ごとに時刻を更新

時計の針の実装

HandViewは時計の針を表現する汎用的な構造体です。以下のパラメータで針の見た目をカスタマイズできます:

  • length: 針の長さ
  • thickness: 針の太さ
  • angle: 針の回転角度

時間計算ロジック

Time構造体は現在時刻に基づいて各針の角度を計算します:

  • 時針:1時間あたり30度(360度÷12)+ 分による微調整
  • 分針:1分あたり6度(360度÷60)
  • 秒針:1秒あたり6度(360度÷60)

これにより、スムーズに動作する本格的なアナログ時計のUIを実現しています。

このコードは、SwiftUIの宣言的なUIプログラミングの特徴を活かしながら、実用的なアプリケーションを構築する良い例となっています。

Discussion