ios - 为什么在不同视图控制器上 segue 后分数没有显示?
问题描述
Iv 创建了一个测验应用程序,该应用程序跟踪用户的分数,直到用户完成。有一个 if 语句 - 当它到达测验结束时,会弹出一个结果视图控制器。我的问题是我想在 resultsViewContoller 的末尾获得相同的分数值。我已经通过 segue 连接了它,并且已经放置了标识符。应用程序运行,但是当我走到尽头时,segue 打开页面但分数没有改变?
我怎么解决这个问题?
用户完成应用程序。我调用 segue 方法,屏幕出现了。
结果视图控制器
import UIKit
class ResultsViewController: UIViewController {
var fruitness = Fruitness()
@IBOutlet weak var finalScoreLabel: UILabel!
var finalScore: String!
override func prepare(for: UIStoryboardSegue, sender: Any?) {
func viewWillAppear(_ animated: Bool) {
finalScoreLabel.text = finalScore
if finalScore != nil {
finalScoreLabel.text = "FINALSCORE:\(String(describing: Int(finalScore!)))"
}
}
}
}
游戏视图控制器
import UIKit
class GameViewController: UIViewController {
@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet private weak var fruitLabel: UILabel!
@IBOutlet private weak var scoreLabel: UILabel!
@IBOutlet weak var replayGame: UIButton!
@IBOutlet weak var optionButton0: UIButton!
@IBOutlet weak var optionButton1: UIButton!
@IBOutlet weak var optionButton2: UIButton!
@IBOutlet weak var optionButton3: UIButton!
@IBOutlet weak var optionButton4: UIButton!
@IBOutlet weak var optionButton5: UIButton!
@IBOutlet weak var optionButton6: UIButton!
@IBOutlet weak var optionButton7: UIButton!
@IBOutlet weak var optionButton8: UIButton!
@IBOutlet private var fruitButtons: [UIButton]!
var score = 0
var fruitness = Fruitness()
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
@IBAction func replayGame(_ sender: UIButton) {
fruitness.restartGame() //Calling restart
updateUI()
}
@IBAction func touchButton(_ sender: UIButton) {
let userAnswer = sender.currentTitle!
//The userGotItRight is = to the checkAnswer function which goes through the fruitOptions array to make sure the answer is corrct. T/F
let userGotItRight = checkAnswer(userAnswer: userAnswer)
if userGotItRight {
//Depending if the user got the answer correct the button turns green/red
sender.backgroundColor = UIColor.green
} else {
sender.backgroundColor = UIColor.red
}
nextFruit() //Calling the next Fruit untill all the fruit items have been displayed.
//This timer is responsible for the UIColors green, red and clear. Without this timer the color drags onto the next fruit.
Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo:nil, repeats: false)
}
// This check answer method needs an input to work. The input is the answer the user-choose (String).
func checkAnswer(userAnswer: String) -> Bool {
// Checks if the user got the answer correct. T/F
if userAnswer == fruitness.fruitOptions[fruitness.fruitNumber].fruit {
fruitness.score += 1 //We increase the value of score when we get the answer right.
// fruitness.finalScorez = fruitness.score
return true
} else {
return false
}
}
//Checks to make sure the eveytime it hits 0 it will shuffle.
func nextFruit() {
if fruitness.fruitNumber == 0 {
fruitness.fruitOptions.shuffle()
}
// print(fruitness.fruitOptions[fruitness.fruitNumber]) //Only gets printed in the consol
if fruitness.fruitNumber + 1 < fruitness.fruitOptions.count {
fruitness.fruitNumber += 1
} else {
self.performSegue(withIdentifier: "goToResultsVC", sender: self) //To call Segue
}
}
//Connecting and controlling oF the Segue and from GameView COntroller -> Results view controller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToResultsVC" {
let destinationVC = segue.destination as! ResultsViewController
destinationVC.finalScore = scoreLabel.text //Printing the final score at the end.
}
}
@objc func updateUI() {
//Controlls the background. Clearing ability between T/F answers.
optionButton0.backgroundColor = UIColor.clear
optionButton1.backgroundColor = UIColor.clear
optionButton2.backgroundColor = UIColor.clear
optionButton3.backgroundColor = UIColor.clear
optionButton4.backgroundColor = UIColor.clear
optionButton5.backgroundColor = UIColor.clear
optionButton6.backgroundColor = UIColor.clear
optionButton7.backgroundColor = UIColor.clear
optionButton8.backgroundColor = UIColor.clear
//The fruit name available that the user needs to match.
fruitLabel.text = fruitness.getFruitText()
//Displaying the progress of the user till they reach the end.
progressBar.progress = fruitness.getProgress()
//Displaying the score at all times
scoreLabel.text = "SCORE: \(fruitness.score)"
}
}
解决方案
您的代码存在许多问题。
首先,在prepare(for:sender:)
触发 segue 的源视图控制器上调用该方法,而不是在目标视图控制器上调用该方法。
其次,您ResultsViewController
有一个viewWillAppear(_:)
嵌套在其方法中的prepare(for:sender:)
方法。不要那样做。该viewWillAppear(_:)
方法必须是视图控制器的顶级方法,否则不会被调用。
此外,viewWillAppear(_:)
方法应该调用super.viewWillAppear(animated)
.
您的 ResultsViewController 的 viewWillAppear 方法应如下所示:
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
finalScoreLabel.text = finalScore
}
您应该在您的prepare(for:sender:)
方法中设置,以便在调用它时具有一个值。GameViewController
finalScore
ResultsViewController
viewWillAppear
finalScore
编辑:
(看起来你最后一部分是正确的。你的 GameViewControllerprepare(for:sender)
似乎设置了finalScore
。但是请注意,你scoreLabel
用来保存你的finalScoreValue
。你不应该在视图对象中保存状态。你应该有一个 varGameViewController
来保存你的分数。您可以GameViewController
设置您的score
var,并didSet()
在 score var 上设置一个方法,将更新的分数值安装到 scoreLabel 中。)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToResultsVC" {
let destinationVC = segue.destination as! ResultsViewController
destinationVC.finalScore = scoreLabel.text //Printing the final score at the end.
}
}
推荐阅读
- postgresql - Postgresql WHERE 子句使用条件子查询
- django - 如何在网格布局中呈现 django formset
- mysql - 将计算日期列添加到 MySQL 数据集
- amazon-web-services - 将 Harbor Helm 与 RDS 一起使用?
- typescript - 使用 Turf.nearPoint() 时应该使用什么样的点?Turf.nearestPoint() 的文档似乎不正确
- node.js - 在 React 中安装依赖项
- html - 使用图像作为拇指 HTML/CSS 制作滚动条
- android - 当适配器上的项目非零时,Firebase 添加新子项
- python - 在 SQL/Python 中使用动态日期值透视雪花查询
- google-cloud-platform - `capture_tpu_profile` 无法访问 TPU