見出し画像

ChatGPTに、クイズアプリのデザイン改修をしてもらったら、すごく効率がよかった!(swiftUI,iPhoneアプリ)

今回は、前回からの続きでクイズアプリのデザイン周りをChatGTPに改修してもらおうと思います!
進行バーやスコア、タイマー表示のデザインについて修正していきます。

(前回の記事)

前回までの画面イメージ


今回修正した内容を反映した画面イメージ


ChatGPTに改修ロジックを教えてもらう

それでは、ChatGPTに改修イメージを伝えて、ロジックを教えてもらいます!

タイマーを「秒:ミリ秒形式」にし、秒数の経過がわかりやすくしたい

class QuizViewModel: ObservableObject {
    @Published var timerValue: Int = 10000  // 初期値を10秒(10000ミリ秒)に設定
    @Published var timerDisplay: String = "10:00"  // 初期表示
    var timer: Timer?

    func startTimer() {
        timer?.invalidate()
        timerValue = 10000  // 初期値を10秒(10000ミリ秒)に設定
        updateTimerDisplay()
        
        timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { timer in
            if self.timerValue > 0 {
                self.timerValue -= 10  // 10ミリ秒ごとにカウントダウン
                self.updateTimerDisplay()
            } else {
                timer.invalidate()
                self.answerQuestion(with: "")  // タイムアウト時は空の回答を送信
            }
        }
    }

    func stopTimer() {
        timer?.invalidate()
    }

    func updateTimerDisplay() {
        let seconds = timerValue / 1000
        let milliseconds = timerValue % 1000 / 10  // ミリ秒を2桁に調整
        timerDisplay = String(format: "%02d:%02d", seconds, milliseconds)
    }

    func answerQuestion(with answer: String) {
        // 問題回答処理
    }
}

上記のロジックにより、タイマーの残り時間を秒とミリ秒の形式で表示することができます。updateTimerDisplayメソッドを使用して、タイマーの残り時間を毎秒更新し、timerDisplayプロパティに秒とミリ秒の形式で文字列に変換します。これにより、タイマーが正しい形式で表示されるようになります。

タイマーの表示が、カウントダウンするたびに、位置が少し動いてしまうので、修正したい

タイマーの表示がカウントダウンするたびに位置が少し動いてしまう問題は、通常、フォントの幅やレイアウトの変動が原因です。これを防ぐためには、タイマー表示の幅を固定し、数字が揃うようにする必要があります。SwiftUIでは、monospacedDigit修飾子を使用することで、数字の幅を固定できます。

struct QuizView: View {
    @ObservedObject var viewModel: QuizViewModel

    var body: some View {
        VStack {
            Text(viewModel.timerDisplay)
                .font(.headline.monospacedDigit())  // Monospaced Digitsを適用
                .frame(width: 100, alignment: .center)  // 幅を固定
                .padding()
            
            // その他のビューの内容

            .onAppear {
                viewModel.startTimer()
            }
            .onDisappear {
                viewModel.stopTimer()
            }
        }
    }
}

monospacedDigit修飾子: 数字の幅を固定することで、カウントダウン中に位置が動かないようにします。
frame(width:alignment:): 固定幅を設定し、中央揃えにすることで、テキストの位置が変わらないようにします。

これにより、タイマー表示がカウントダウン中に動かないように固定され、安定した位置に表示されるようになります。

スコアとタイマーにアイコンをつけたい

HStack: アイコンとテキストを横並びに配置するために使用します。
Image(systemName:): SF Symbolsを使ってアイコンを表示します。ここでは「star.fill」と「clock.fill」を使用していますが、必要に応じて他のアイコンに変更できます。
foregroundColor: アイコンの色を設定します。

これにより、スコアとタイマーの左側にそれぞれアイコンを表示することができます。アイコンとテキストが見やすく整列され、ユーザーにとってわかりやすいインターフェースになります。

struct QuizView: View {
    @ObservedObject var viewModel: QuizViewModel

    var body: some View {
        VStack {
            Text(viewModel.timerDisplay)
                .font(.headline.monospacedDigit())  // Monospaced Digitsを適用
                .frame(width: 100, alignment: .center)  // 幅を固定
                .padding()
            
            // その他のビューの内容

            HStack {
                Image(systemName: "star.fill")  // スコアのアイコン
                    .foregroundColor(.yellow)
                Text("Score: \(viewModel.score)")
            }
            .padding()

            HStack {
                Image(systemName: "clock.fill")  // タイマーのアイコン
                    .foregroundColor(.blue)
                Text(viewModel.timerDisplay)
                    .font(.headline.monospacedDigit())  // Monospaced Digitsを適用
                    .frame(width: 100, alignment: .center)  // 幅を固定
            }
            .padding()

            .onAppear {
                viewModel.startTimer()
            }
            .onDisappear {
                viewModel.stopTimer()
            }
        }
    }
}

進行バーの太くして、アニメーションのように動くようにしたい

カスタム ProgressViewStyle: ThickProgressViewStyleを作成し、バーの太さとアニメーションをカスタマイズします。

ProgressView に適用: カスタムスタイルをProgressViewに適用して、デザインを変更します。

struct ThickProgressViewStyle: ProgressViewStyle {
    func makeBody(configuration: Configuration) -> some View {
        ZStack(alignment: .leading) {
            RoundedRectangle(cornerRadius: 10)
                .frame(height: 20)  // バーの高さを設定
                .foregroundColor(Color.gray.opacity(0.3))
            
            RoundedRectangle(cornerRadius: 10)
                .frame(width: CGFloat(configuration.fractionCompleted ?? 0) * 200, height: 20)  // バーの高さを設定
                .foregroundColor(.blue)
                .animation(.easeInOut(duration: 0.5), value: configuration.fractionCompleted)
        }
    }
}
struct QuizView: View {
    @ObservedObject var viewModel: QuizViewModel

    var body: some View {
        VStack {
            ProgressView(value: Double(viewModel.currentQuestionIndex), total: Double(viewModel.questions.count))
                .progressViewStyle(ThickProgressViewStyle())
                .padding()
            
            // その他のビューの内容
            
            .onAppear {
                viewModel.startTimer()
            }
            .onDisappear {
                viewModel.stopTimer()
            }
        }
    }
}

おわりに

最後まで読んで頂きありがとうございます!

今回は、ChatGPTに改修イメージが上手く伝わったようで、だいぶスムーズに完成することができました!(機能改修ではなく、デザイン周りの改修だったので、ChatGPTのアウトプットイメージが出しやすかったのかな?)

デザインがいい感じになると、やる気も上がるので、もうちょっとデザイン周りについてブラッシュアップしていこうと思います!

おまけ

最近、ChatGPTを使用し、色々なことを模索しています。
もしよければ、以下の記事も見て頂けると嬉しいです!






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