为什么在不同的视图控制器上 segue 后分数不显示?
Why isn't the score showing up after segue on different view controller?
我创建了一个测验应用程序,它会跟踪用户的分数,直到用户完成为止。有一个 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(_:)
方法必须是视图控制器的 top-level 方法,否则不会被调用。
另外,viewWillAppear(_:)
方法应该调用 super.viewWillAppear(animated)
.
您的 ResultsViewController 的 viewWillAppear 方法应如下所示:
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
finalScoreLabel.text = finalScore
}
GameViewController
中的 prepare(for:sender:)
方法应在 ResultsViewController
中设置 finalScore
,以便在调用其 viewWillAppear
时,finalScore
有一个值。
编辑:
(看起来你的最后一部分是正确的。你的 GameViewController 的 prepare(for:sender)
确实设置了 finalScore
。但是请注意,你正在使用 scoreLabel
来保存你的 finalScoreValue
。你不应该在视图对象中保存状态。你应该在 GameViewController
中有一个 var 来保存你的分数。你可以让 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.
}
}
也许您想将重复的代码重构为这个代码:
let optionButtonArray = [optionButton0,optionButton1 ...]
optionButtonArray.forEach { [=10=].backgroundColor = UIColor.clear }
我创建了一个测验应用程序,它会跟踪用户的分数,直到用户完成为止。有一个 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(_:)
方法必须是视图控制器的 top-level 方法,否则不会被调用。
另外,viewWillAppear(_:)
方法应该调用 super.viewWillAppear(animated)
.
您的 ResultsViewController 的 viewWillAppear 方法应如下所示:
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
finalScoreLabel.text = finalScore
}
GameViewController
中的 prepare(for:sender:)
方法应在 ResultsViewController
中设置 finalScore
,以便在调用其 viewWillAppear
时,finalScore
有一个值。
编辑:
(看起来你的最后一部分是正确的。你的 GameViewController 的 prepare(for:sender)
确实设置了 finalScore
。但是请注意,你正在使用 scoreLabel
来保存你的 finalScoreValue
。你不应该在视图对象中保存状态。你应该在 GameViewController
中有一个 var 来保存你的分数。你可以让 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.
}
}
也许您想将重复的代码重构为这个代码:
let optionButtonArray = [optionButton0,optionButton1 ...]
optionButtonArray.forEach { [=10=].backgroundColor = UIColor.clear }