Mercurial > public > geoquiz
comparison GeoQuiz/GuessTheFlagView.swift @ 26:425078c01194
refactor code
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Wed, 09 Nov 2022 10:30:01 +0100 |
parents | 02dcebb8cc4a |
children | 3f4b366d476d |
comparison
equal
deleted
inserted
replaced
25:b3df0f5dc750 | 26:425078c01194 |
---|---|
6 // | 6 // |
7 | 7 |
8 import SwiftUI | 8 import SwiftUI |
9 | 9 |
10 struct GuessTheFlagView: View { | 10 struct GuessTheFlagView: View { |
11 @StateObject var game = CountryGameController() | 11 @StateObject var gameController = CountryGameController() |
12 | 12 |
13 @Environment(\.managedObjectContext) var moc | 13 @Environment(\.managedObjectContext) var moc |
14 | 14 |
15 var body: some View { | 15 var body: some View { |
16 ZStack { | 16 ZStack { |
17 LinearGradient(gradient: .main, startPoint: .top, endPoint: .bottom) | 17 LinearGradient(gradient: .main, startPoint: .top, endPoint: .bottom) |
18 .ignoresSafeArea() | 18 .ignoresSafeArea() |
19 | 19 |
20 GeometryReader { geo in | 20 GeometryReader { geo in |
21 VStack { | 21 VStack { |
22 GameToolbar(game: game, color: .mayaBlue) | 22 GameToolbar(gameController: gameController, color: .mayaBlue) |
23 .padding(.bottom) | 23 .padding(.bottom) |
24 | 24 |
25 VStack(alignment: .center, spacing: 10) { | 25 VStack(alignment: .center, spacing: 10) { |
26 Text("Question \(game.questionCounter) of \(game.data.count)") | 26 Text("Question \(gameController.questionCounter) of \(gameController.data.count)") |
27 .font(.title3) | 27 .font(.title3) |
28 .foregroundColor(.white.opacity(0.7)) | 28 .foregroundColor(.white.opacity(0.7)) |
29 | 29 |
30 Text("What is the flag of") | 30 Text("What is the flag of") |
31 .font(.title) | 31 .font(.title) |
32 .fontWeight(.semibold) | 32 .fontWeight(.semibold) |
33 .foregroundColor(.white) | 33 .foregroundColor(.white) |
34 | 34 |
35 Text("\(game.correctAnswer.key)?") | 35 Text("\(gameController.correctAnswer.key)?") |
36 .font(.largeTitle.bold()) | 36 .font(.largeTitle.bold()) |
37 .foregroundColor(.white) | 37 .foregroundColor(.white) |
38 .multilineTextAlignment(.center) | |
38 | 39 |
39 } | 40 } |
40 | 41 |
41 Spacer() | 42 Spacer() |
42 VStack(spacing: 30) { | 43 VStack(spacing: 30) { |
43 ForEach(Array(game.userChoices.keys), id: \.self) { countryName in | 44 ForEach(Array(gameController.userChoices.keys), id: \.self) { countryName in |
44 Button { | 45 Button { |
45 game.answer((key: countryName, value: game.data[countryName]!)) { | 46 gameController.answer( |
46 game.selector() | 47 choice: (key: countryName, value: gameController.data[countryName]!), |
48 wrongMessage: "That's the flag of \(countryName)" | |
49 ) { | |
50 gameController.selector() | |
47 } | 51 } |
48 } label: { | 52 } label: { |
49 Circle() | 53 |
50 .stroke(.white, lineWidth: 6) | 54 /* |
51 .frame(height: geo.size.height * 0.15) | 55 THE PROBLEM: |
52 .shadow(radius: 10) | 56 SwiftUI caches the image when it's shown using the `Image(string)` API. |
57 Once the image is not showed anymore, SwiftUI doesn't release memory, | |
58 so it keeps caching new images until the app crashes | |
59 UIImage(contentsOfFile: path) doesn't cache the image | |
60 | |
61 THE SOLUTION: | |
62 Using `UIImage(contentsOfFile: path)` images aren't cached. | |
63 */ | |
64 | |
65 let flag = gameController.data[countryName]!.flag | |
66 let flagPath = Bundle.main.path(forResource: flag, ofType: "png")! | |
67 | |
68 RoundedRectangle(cornerRadius: 20) | |
69 .foregroundColor(.white.opacity(0.5)) | |
70 .frame(width: geo.size.height * 0.3, height: geo.size.height * 0.15) | |
53 .overlay( | 71 .overlay( |
54 Image(game.data[countryName]!.flag) | 72 Image(uiImage: UIImage(contentsOfFile: flagPath)!) |
55 .renderingMode(.original) | |
56 .resizable() | 73 .resizable() |
57 .scaledToFill() | 74 .scaledToFit() |
58 .clipShape(Circle()) | 75 .cornerRadius(20) |
76 .shadow(radius: 10) | |
77 .padding() | |
59 ) | 78 ) |
60 } | 79 } |
61 } | 80 } |
62 } | 81 } |
63 | 82 |
65 } | 84 } |
66 .padding() | 85 .padding() |
67 } | 86 } |
68 } | 87 } |
69 .navigationBarHidden(true) | 88 .navigationBarHidden(true) |
70 .modifier(GameAlertsModifier(game: game, gameType: .guessTheFlag, moc: moc)) | 89 .modifier(GameAlertsModifier(gameController: gameController, gameType: .guessTheFlag, moc: moc)) |
71 } | 90 } |
72 } | 91 } |
73 | 92 |
74 struct GuessTheFlagView_Previews: PreviewProvider { | 93 struct GuessTheFlagView_Previews: PreviewProvider { |
75 static var previews: some View { | 94 static var previews: some View { |
76 GuessTheFlagView() | 95 GuessTheFlagView() |
77 .previewDevice(PreviewDevice(rawValue: "iPhone 14 Pro Max")) | |
78 .previewDisplayName("iPhone 14 Pro Max") | |
79 | |
80 GuessTheFlagView() | |
81 .previewDevice(PreviewDevice(rawValue: "iPad Pro (12.9-inch) (5th generation)")) | |
82 .previewDisplayName("iPad Pro (12.9-inch)") | |
83 | |
84 GuessTheFlagView() | |
85 .previewDevice(PreviewDevice(rawValue: "iPhone 8")) | |
86 .previewDisplayName("iPhone 8") | |
87 } | 96 } |
88 } | 97 } |