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 }