diff --git a/PrimePickApp.xcodeproj/project.pbxproj b/PrimePickApp.xcodeproj/project.pbxproj index 1dcc7d1..95c396d 100644 --- a/PrimePickApp.xcodeproj/project.pbxproj +++ b/PrimePickApp.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 4F65A3992C01019000065A53 /* Difficulty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F65A3982C01019000065A53 /* Difficulty.swift */; }; 4F8BE16C2BF4FFB000D7CF0E /* PrimeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F8BE16B2BF4FFB000D7CF0E /* PrimeData.swift */; }; 4F8BE16E2BF504BB00D7CF0E /* QuizView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F8BE16D2BF504BB00D7CF0E /* QuizView.swift */; }; + 4FEC65B12C01164800A8B731 /* SelectDifficultyButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FEC65B02C01164800A8B731 /* SelectDifficultyButtonView.swift */; }; + 4FEC65B42C01184E00A8B731 /* Text+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FEC65B32C01184E00A8B731 /* Text+Extension.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -41,6 +43,8 @@ 4F8BE16B2BF4FFB000D7CF0E /* PrimeData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimeData.swift; sourceTree = ""; }; 4F8BE16D2BF504BB00D7CF0E /* QuizView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuizView.swift; sourceTree = ""; }; 4FC177B82BEEAB2C00447A06 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 4FEC65B02C01164800A8B731 /* SelectDifficultyButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectDifficultyButtonView.swift; sourceTree = ""; }; + 4FEC65B32C01184E00A8B731 /* Text+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Text+Extension.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -74,17 +78,13 @@ isa = PBXGroup; children = ( 4F65A3972C0100FD00065A53 /* Enum */, - 4FC177B82BEEAB2C00447A06 /* Info.plist */, + 4FEC65B22C0117FC00A8B731 /* Extension */, + 4FEC65B52C01234C00A8B731 /* View */, 4F0C82812BC8247500E1480E /* PrimePickApp.swift */, - 4F0C82832BC8247500E1480E /* MainView.swift */, - 4F8BE16D2BF504BB00D7CF0E /* QuizView.swift */, - 4F2239212BFC9DEB004C71A6 /* QuizTimeLimitView.swift */, - 4F2239252BFD0873004C71A6 /* QuizIndexView.swift */, - 4F42C7A32BF76E7700F92FBB /* QuizNumberView.swift */, - 4F2239232BFCEEF0004C71A6 /* QuizButtonView.swift */, 4F8BE1682BF4FB8E00D7CF0E /* QuizData */, 4F0C82852BC8247600E1480E /* Assets.xcassets */, 4F42C7A52BF7756200F92FBB /* ColorAssets.xcassets */, + 4FC177B82BEEAB2C00447A06 /* Info.plist */, 4F0C82872BC8247600E1480E /* PrimePickApp.entitlements */, 4F0C82882BC8247600E1480E /* Preview Content */, ); @@ -117,6 +117,36 @@ path = QuizData; sourceTree = ""; }; + 4FEC65B22C0117FC00A8B731 /* Extension */ = { + isa = PBXGroup; + children = ( + 4FEC65B32C01184E00A8B731 /* Text+Extension.swift */, + ); + path = Extension; + sourceTree = ""; + }; + 4FEC65B52C01234C00A8B731 /* View */ = { + isa = PBXGroup; + children = ( + 4F0C82832BC8247500E1480E /* MainView.swift */, + 4FEC65B02C01164800A8B731 /* SelectDifficultyButtonView.swift */, + 4FEC65B62C01252800A8B731 /* Quiz */, + ); + path = View; + sourceTree = ""; + }; + 4FEC65B62C01252800A8B731 /* Quiz */ = { + isa = PBXGroup; + children = ( + 4F8BE16D2BF504BB00D7CF0E /* QuizView.swift */, + 4F2239252BFD0873004C71A6 /* QuizIndexView.swift */, + 4F42C7A32BF76E7700F92FBB /* QuizNumberView.swift */, + 4F2239212BFC9DEB004C71A6 /* QuizTimeLimitView.swift */, + 4F2239232BFCEEF0004C71A6 /* QuizButtonView.swift */, + ); + path = Quiz; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -194,11 +224,13 @@ 4F02A57D2BF62F61003DF310 /* PrimeQuizEntity.swift in Sources */, 4F65A3992C01019000065A53 /* Difficulty.swift in Sources */, 4F0C82842BC8247500E1480E /* MainView.swift in Sources */, + 4FEC65B12C01164800A8B731 /* SelectDifficultyButtonView.swift in Sources */, 4F8BE16E2BF504BB00D7CF0E /* QuizView.swift in Sources */, 4F2239222BFC9DEB004C71A6 /* QuizTimeLimitView.swift in Sources */, 4F0C82822BC8247500E1480E /* PrimePickApp.swift in Sources */, 4F02A57F2BF63A43003DF310 /* QuizDataManager.swift in Sources */, 4F8BE16C2BF4FFB000D7CF0E /* PrimeData.swift in Sources */, + 4FEC65B42C01184E00A8B731 /* Text+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/PrimePickApp/Extension/Text+Extension.swift b/PrimePickApp/Extension/Text+Extension.swift new file mode 100644 index 0000000..eee909c --- /dev/null +++ b/PrimePickApp/Extension/Text+Extension.swift @@ -0,0 +1,45 @@ +// +// Text+Extension.swift +// PrimePickApp +// +// Created by 村石 拓海 on 2024/05/25. +// + +import SwiftUI + +public extension View { + func gamingText() -> some View { + self.modifier(GamingText()) + } +} + +struct GamingText: ViewModifier { + @State private var hue: Double = 0 + + func body(content: Content) -> some View { + content + .foregroundColor(Color.white) + .overlay( + LinearGradient( + gradient: Gradient(colors: [ + Color.red, Color.orange, Color.yellow, Color.green, + Color.blue, Color.purple, Color.red + ]), + startPoint: .leading, + endPoint: .trailing + ) + .mask(content) + .hueRotation(Angle(degrees: hue)) + ) + .onAppear { + withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) { + hue = 360 + } + } + } +} + +#Preview { + Text("Gaming ON!") + .gamingText() +} diff --git a/PrimePickApp/MainView.swift b/PrimePickApp/MainView.swift deleted file mode 100644 index d65ec4a..0000000 --- a/PrimePickApp/MainView.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// ContentView.swift -// PrimePickApp -// -// Created by 村石 拓海 on 2024/04/11. -// - -import SwiftUI - -struct MainView: View { - @State private var hue: Double = 0 - - var body: some View { - NavigationStack { - ZStack { - Color("appBlue") - .ignoresSafeArea() - - VStack { - Spacer() - - Text("Prime Pick") - .font(.custom("Helvetica Neue", size: 60)) - .foregroundStyle(.black) - .fontWeight(.bold) - .offset(x: 2, y: 2) - .foregroundColor(Color.white) // 文字自体を白に設定 - .overlay( - LinearGradient( - gradient: Gradient(colors: [ - Color.red, Color.orange, Color.yellow, Color.green, - Color.blue, Color.purple, Color.red - ]), - startPoint: .leading, - endPoint: .trailing - ) - .mask( - Text("Prime Pick") - .font(.custom("Helvetica Neue", size: 60)) - .fontWeight(.bold) - ) - .hueRotation(Angle(degrees: hue)) - ) - .onAppear { - withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) { - hue = 360 - } - } - - Spacer() - - NavigationLink(destination: LazyView(QuizView(difficulty: .hard))) { - Text(Difficulty.hard.rawValue) - .font(.system(size: 24, weight: .bold, design: .rounded)) - .padding() - .frame(maxWidth: .infinity) - .background( - LinearGradient(gradient: Gradient(colors: [Color.red, Color.purple]), - startPoint: .topLeading, - endPoint: .bottomTrailing) - ) - .foregroundColor(.white) - .cornerRadius(20) - .shadow(color: Color.black.opacity(0.3), radius: 10, x: 5, y: 5) - .overlay( - RoundedRectangle(cornerRadius: 20) - .stroke(Color.white.opacity(0.7), lineWidth: 2) - ) - } - .padding(.horizontal, 50) - .padding(.bottom, 10) - - NavigationLink(destination: LazyView(QuizView(difficulty: .normal))) { - Text(Difficulty.normal.rawValue) - .font(.system(size: 24, weight: .bold, design: .rounded)) - .padding() - .frame(maxWidth: .infinity) - .background( - LinearGradient(gradient: Gradient(colors: [Color.purple, Color.blue]), - startPoint: .topLeading, - endPoint: .bottomTrailing) - ) - .foregroundColor(.white) - .cornerRadius(20) - .shadow(color: Color.black.opacity(0.3), radius: 10, x: 5, y: 5) - .overlay( - RoundedRectangle(cornerRadius: 20) - .stroke(Color.white.opacity(0.7), lineWidth: 2) - ) - } - .padding(.horizontal, 50) - .padding(.bottom, 10) - - NavigationLink(destination: LazyView(QuizView(difficulty: .easy))) { - Text(Difficulty.easy.rawValue) - .font(.system(size: 24, weight: .bold, design: .rounded)) - .padding() - .frame(maxWidth: .infinity) - .background( - LinearGradient(gradient: Gradient(colors: [Color.green, Color.yellow]), - startPoint: .topLeading, - endPoint: .bottomTrailing) - ) - .foregroundColor(.white) - .cornerRadius(20) - .shadow(color: Color.black.opacity(0.3), radius: 10, x: 5, y: 5) - .overlay( - RoundedRectangle(cornerRadius: 20) - .stroke(Color.white.opacity(0.7), lineWidth: 2) - ) - } - .padding(.horizontal, 50) - .padding(.bottom, 10) - - Spacer() - } - } - } - } -} - -struct LazyView: View { - let content: () -> Content - - init(_ content: @autoclosure @escaping () -> Content) { - self.content = content - } - - var body: Content { - content() - } -} - -struct RainbowTextModifier: AnimatableModifier { - var hue: Double - - var animatableData: Double { - get { hue } - set { hue = newValue } - } - - func body(content: Content) -> some View { - content - .foregroundColor(Color(hue: hue, saturation: 1, brightness: 1)) - .animation(Animation.linear(duration: 2).repeatForever(autoreverses: false)) - } -} - -#Preview { - MainView() -} diff --git a/PrimePickApp/View/MainView.swift b/PrimePickApp/View/MainView.swift new file mode 100644 index 0000000..39dc364 --- /dev/null +++ b/PrimePickApp/View/MainView.swift @@ -0,0 +1,66 @@ +// +// ContentView.swift +// PrimePickApp +// +// Created by 村石 拓海 on 2024/04/11. +// + +import SwiftUI + +struct MainView: View { + @State private var hue: Double = 0 + + var body: some View { + NavigationStack { + ZStack { + Color("appBlue") + .ignoresSafeArea() + + VStack { + Spacer() + + Text("Prime Pick") + .gamingText() + .font(.custom("Helvetica Neue", size: 60)) + .fontWeight(.bold) + + + Spacer() + + SelectDifficultyButtonView() + + Spacer() + } + } + } + } +} + +extension Difficulty { + public var gradientColors: [Color] { + switch self { + case .easy: + return [Color.green, Color.yellow] + case .normal: + return [Color.purple, Color.blue] + case .hard: + return [Color.red, Color.purple] + } + } +} + +struct LazyView: View { + let content: () -> Content + + init(_ content: @autoclosure @escaping () -> Content) { + self.content = content + } + + var body: Content { + content() + } +} + +#Preview { + MainView() +} diff --git a/PrimePickApp/QuizButtonView.swift b/PrimePickApp/View/Quiz/QuizButtonView.swift similarity index 100% rename from PrimePickApp/QuizButtonView.swift rename to PrimePickApp/View/Quiz/QuizButtonView.swift diff --git a/PrimePickApp/QuizIndexView.swift b/PrimePickApp/View/Quiz/QuizIndexView.swift similarity index 100% rename from PrimePickApp/QuizIndexView.swift rename to PrimePickApp/View/Quiz/QuizIndexView.swift diff --git a/PrimePickApp/QuizNumberView.swift b/PrimePickApp/View/Quiz/QuizNumberView.swift similarity index 93% rename from PrimePickApp/QuizNumberView.swift rename to PrimePickApp/View/Quiz/QuizNumberView.swift index f226416..4b1091a 100644 --- a/PrimePickApp/QuizNumberView.swift +++ b/PrimePickApp/View/Quiz/QuizNumberView.swift @@ -65,6 +65,10 @@ struct QuizNumberView_Previews: PreviewProvider { @State static var quizNumber = 3 static var previews: some View { - QuizNumberView(quizNumber: $quizNumber, difficulty: .easy, quizData: [PrimeQuizEntity(quizId: 0, number: 3, isCorrect: true)]) + QuizNumberView( + quizNumber: $quizNumber, + difficulty: .easy, + quizData: [PrimeQuizEntity(quizId: 0, number: 3, isCorrect: true)] + ) } } diff --git a/PrimePickApp/QuizTimeLimitView.swift b/PrimePickApp/View/Quiz/QuizTimeLimitView.swift similarity index 100% rename from PrimePickApp/QuizTimeLimitView.swift rename to PrimePickApp/View/Quiz/QuizTimeLimitView.swift diff --git a/PrimePickApp/QuizView.swift b/PrimePickApp/View/Quiz/QuizView.swift similarity index 100% rename from PrimePickApp/QuizView.swift rename to PrimePickApp/View/Quiz/QuizView.swift diff --git a/PrimePickApp/View/SelectDifficultyButtonView.swift b/PrimePickApp/View/SelectDifficultyButtonView.swift new file mode 100644 index 0000000..38c8e9e --- /dev/null +++ b/PrimePickApp/View/SelectDifficultyButtonView.swift @@ -0,0 +1,49 @@ +// +// SelectDifficultyButtonView.swift +// PrimePickApp +// +// Created by 村石 拓海 on 2024/05/25. +// + +import SwiftUI + +struct SelectDifficultyButtonView: View { + var body: some View { + VStack { + selectDifficultyButton(difficulty: .hard) + + selectDifficultyButton(difficulty: .normal) + + selectDifficultyButton(difficulty: .easy) + } + } +} + +extension SelectDifficultyButtonView { + func selectDifficultyButton(difficulty: Difficulty) -> some View { + NavigationLink(destination: LazyView(QuizView(difficulty: difficulty))) { + Text(difficulty.rawValue) + .font(.system(size: 24, weight: .bold, design: .rounded)) + .padding() + .frame(maxWidth: .infinity) + .background( + LinearGradient(gradient: Gradient(colors: difficulty.gradientColors), + startPoint: .topLeading, + endPoint: .bottomTrailing) + ) + .foregroundColor(.white) + .cornerRadius(20) + .shadow(color: Color.black.opacity(0.3), radius: 10, x: 5, y: 5) + .overlay( + RoundedRectangle(cornerRadius: 20) + .stroke(Color.white.opacity(0.7), lineWidth: 2) + ) + .padding(.horizontal, 50) + .padding(.bottom, 10) + } + } +} + +#Preview { + SelectDifficultyButtonView() +}