J'ai créé un jeu incrémentiel simple. Je veux que même si je vais dans un VC différent et que je retourne au jeu, ou que je rouvre le jeu, il affichera le score actuel. Mon problème est que si je quitte le jeu, le score reviendra à zéro. Je ne veux pas que cela se produise. Le score ne doit pas être réinitialisé. J'ai entendu dire que je pourrais utiliser UserDefaults mais je n'y suis pas du tout familier. Si vous pouvez expliquer en utilisant du code, ce serait mieux. Merci.
import UIKit
class CookieClickerVC: UIViewController {
@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
formatItems()
let defaults = UserDefaults.standard
defaults.set(0, forKey: "goldCount")
}
@IBAction func getGoldClicked(_ sender: Any) {
goldCount += 1
numberOfGold.text = ("\(goldCount)")
}`
aussi, vous avez peut-être déjà compris, mais goldCount est un identifiant non résolu. Comment changer le code après avoir cliqué sur le bouton?
5 Réponses :
import UIKit
class CookieClickerVC: UIViewController {
@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!
private var goldCount: Int = Int()
override func viewDidLoad() {
super.viewDidLoad()
formatItems()
}
@IBAction func getGoldClicked(_ sender: Any) {
goldCount += 1
numberOfGold.text = ("\(goldCount)")
UserDefaults.standard.set(goldCount, forKey: "goldCount")
UserDefaults.standard.synchronize()
//To get the count again you can use
print(UserDefaults.standard.integer(forKey: "goldCount")
}
Whenever there is an increment you can save the value of goldCount like this in your UserDefault and I have also added how can you fetch the same value from UserDefault.
Vous pouvez utiliser ces fonctions pour obtenir et définir le score
func getScore()-> Int {
let defaults = UserDefaults.standard
return defaults.integer(forKey: "goldCount")
}
}
// defaults.synchronize () c'est inutile p>
class CookieClickerVC: UIViewController {
@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!
lazy var goldCount : Int = 0 {
didSet {
numberOfGold.text = ("\(goldCount)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
formatItems()
goldCount = getScore()
}
@IBAction func getGoldClicked(_ sender: Any) {
goldCount += 1
savescore(goldCount)
}
// Save and Get methods ..
func saveScore(_ score:Int) {
let defaults = UserDefaults.standard
defaults.set(score, forKey: "goldCount")
// defaults.synchronize() its [unnecessary][1]
}
Étape 1: déclarez votre variable goldCount et définissez la valeur initiale sur 0
Étape 2: strong > sur viewDidLoad , récupérez la valeur stockée dans UserDefaults et réglez-la sur goldCount
Étape 3: Mettez également à jour votre libellé
Étape 4: Mettez à jour la valeur de goldCount dans userDefaults
import UIKit
class CookieClickerVC: UIViewController {
@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!
//Step1: declare your goldCount variable and set initial value to 0
var goldCount = 0
override func viewDidLoad() {
super.viewDidLoad()
formatItems()
//Step2: on viewDidLoad, get the value stored in the UserDefaults and set it to goldCount
goldCount = UserDefaults.standard.integer(forKey: "goldCount")
//Step3: then also update your label
numberOfGold.text = ("\(goldCount)")
}
@IBAction func getGoldClicked(_ sender: Any) {
goldCount += 1
numberOfGold.text = ("\(goldCount)")
//Step4: update the value of goldCount in userDefaults
UserDefaults.standard.set(goldCount, forKey: "goldCount")
}
}
Essayez ce qui suit
class ViewController: UIViewController {
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var highScore: UILabel!
//declare your count variable globally
var goldCount : Int = 0
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
//get the highscore and then set it to label
let userHighScore = getUserScore()
highScore.text = "\(userHighScore)"
}
@IBAction func goldButtonClicked(_ sender: Any) {
goldCount += 1
numberOfGold.text = "\(goldCount)"
}
//function to say game finished and store the score in userdefault
//call this function when the gameHasFinished
func gameFinished() {
saveUserScore(goldCount)
}
func saveUserScore(_ score:Int){
defaults.set(score, forKey: "goldCount")
}
func getUserScore()-> Int {
return defaults.integer(forKey: "goldCount")
}
}
Apple dit que synchronize () ne doit pas être utilisé a>, à part ça c'est une bonne solution globale!
Vous pouvez modifier votre fonction viewDidLoad pour vérifier d'abord la clé "goldCount" dans UserDefaults , et si elle a une valeur, utilisez-la. Sinon, définissez simplement le score sur 0.
override func viewDidLoad() {
super.viewDidLoad()
formatItems()
let defaults = UserDefaults.standard
if let savedScore = defaults.value(forKey: "goldCount") as? Int {
goldCount = savedScore
} else {
defaults.set(0, forKey: "goldCount")
}
}
Vous pouvez définir "goldCount" comme var goldCount: Int = 0 sous votre IBOutlet s.
Aussi comme optimisation supplémentaire, vous pouvez extraire la chaîne "goldCount" à utiliser comme let goldCountKey: String = "goldCount" et l'utiliser comme valeurs par défaut. set (0, forKey: goldCountKey) . Éviter les chaînes codées en dur est une bonne pratique à mon avis, mais pas si cruciale dans ce cas.
Pour enregistrer la nouvelle valeur à chaque clic, ajoutez UserDefaults.standard.set (goldCount, forKey : goldCountKey) dans getGoldClicked . Une autre idée ici serait d'ajouter ceci dans la fonction willTerminate de votre AppDelegate pour vous assurer que votre valeur est enregistrée lorsque l'application est terminée. Bien que cela nécessitera des références à la valeur goldCount, donc pas de précipitation.
J'espère que cela aide!
defaults.integer (forKey: "goldCount") c'est une valeur "non facultative". pas besoin d'if-let.
Oui, mon mal. J'utilise généralement value (forKey :) et je la lance. Correction de la réponse, merci!