You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI开发游戏如何实现最高分退出APP后仍可持久化保存?

解决方案

你可以用SwiftUI内置的@AppStorage属性包装器实现最高分的持久化,它会自动将数值存储到系统UserDefaults中,应用重启后自动读取已保存的数值,无需手动编写读写逻辑,适配iOS 14及以上版本。

修改步骤

  1. 替换highScore的属性声明
    将原来的:
@State private var highScore = 0

修改为:

@AppStorage("highScore") private var highScore = 0

括号内的"highScore"是本地存储的唯一键名,保持固定即可。

  1. 原有更新最高分的逻辑无需额外调整,@AppStorage会在你给highScore赋值时自动同步到本地存储,下次应用启动时会自动读取本地保存的值作为初始值。

适配iOS 13及以下版本的方案

如果需要兼容更低版本系统,可以手动操作UserDefaults实现读写:

  • 初始化时读取本地存储的最高分:
@State private var highScore = UserDefaults.standard.integer(forKey: "highScore")
  • 调整最高分更新逻辑,赋值后同步写入本地:
func highScoreSet() {
    if highScore < userScore {
        highScore = userScore
        UserDefaults.standard.set(highScore, forKey: "highScore")
    }
}

注:你原有highScoreSet方法的入参number全程没有用到,属于冗余参数,可以直接删除,调用时也不需要传值。

优化后的完整代码

import SwiftUI

struct Europe: View {
    @State private var countries = ["Albania", "etc."].shuffled()
    
    // 修正拼写错误,原corrrectAnswer改为correctAnswer
    @State private var correctAnswer = Int.random(in: 0...5)
    @State private var showingScore = false
    @State private var scoreTitle = ""
    @State private var userScore = 0
    // 用@AppStorage实现持久化
    @AppStorage("highScore") private var highScore = 0
    

    var body: some View {
        ZStack{
            LinearGradient(gradient: Gradient(colors: [.white,.blue]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(.all)
            VStack(spacing:30){
                VStack{
                    Text("Tap the flag of")
                        .foregroundColor(.black)
                        .fontWeight(.black)
                    Text(countries[correctAnswer])
                        .foregroundColor(.black)
                        .font(.largeTitle)
                        .fontWeight(.black)
                }
                
                VStack(spacing:50){
                    
                    HStack(spacing:40) {
                        VStack(spacing:40) {
                            ForEach(0..<3){ number in
                                Button(action: {
                                    self.flagTapped(number)
                                    self.highScoreSet()
                                }){
                                    Image(self.countries[number])
                                        .resizable()
                                            .frame(width: 130, height: 100)
                                        .clipShape(Capsule())
                                        .overlay(Capsule().stroke(Color.black,lineWidth: 1))
                                        .shadow(color: .black, radius: 2)
                                }
                                
                                
                            }
                        }
                        VStack(spacing:40) {
                            ForEach(4..<7){ number in
                                Button(action: {
                                    self.flagTapped(number)
                                    self.highScoreSet()
                                }){
                                    Image(self.countries[number])
                                        .resizable()
                                            .frame(width: 130, height: 100)
                                        .clipShape(Capsule())
                                        .overlay(Capsule().stroke(Color.black,lineWidth: 1))
                                        .shadow(color: .black, radius: 2)
                                }
                                
                                
                            }
                        }
                    }
                    
                    VStack{
                        Text("Score:  \(userScore)")
                            .foregroundColor(.white)
                            .fontWeight(.black)
                            .font(.subheadline)
                        
                        Text("High Score: \(highScore)")

                            .foregroundColor(.white)
                            .fontWeight(.black)
                            .font(.subheadline)
                        

                    }

                    Spacer()
                }
            }
        }
        .alert(isPresented: $showingScore){
            Alert(title: Text(scoreTitle), message: Text("Your score is \(userScore)"), dismissButton: .default(Text("Continue")){
                self.askQuestion()})
        }
    }

    // 移除冗余的number参数
    func highScoreSet(){
        if highScore < userScore {
            highScore = userScore
        }
    }

    func flagTapped(_ number: Int){
        if number == correctAnswer{
            scoreTitle = "Right"
            userScore += 1
        }
        else {
            scoreTitle = "Wrong!\n Thats the flag of \(countries[correctAnswer])"
            userScore = 0
        }
        showingScore = true
    }

    func askQuestion(){
        countries.shuffle()
        correctAnswer = Int.random(in: 0...5)
    }
    
}

struct Europe_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

内容的提问来源于stack exchange,提问作者Adal Chang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:45:03