如何在视图控制器之间传递数据-不起作用

时间:2019-01-20 21:24:35

标签: swift uikit uilabel interface-builder uistoryboardsegue

我正在尝试将玩家得分从VC1传递到显示所有玩家当前得分的视图(4)。显示视图位于与定义和存储玩家得分不同的视图控制器上。

我已经完成了prepare(segue),并且无法将其他变量传递给显示VC(ThirdViewController)。但是当我尝试将玩家分数分配给uilabel.text时,它告诉我我解开了一个nil值

我什至试图将标签文本设置为静态字符串,但仍然会收到nil错误。

class ViewController: UIViewController {

var name = String()

var player1Score = 1
var player2Score = 2
var player3Score = 3
var player4Score = 4

//MARK: ********* IBOutlets **********
@IBOutlet weak var playerSegmentOutlet: UISegmentedControl!
@IBOutlet weak var diceSegmentOutlet: UISegmentedControl!
@IBOutlet weak var targetScoreSliderOutlet: UISlider!
@IBOutlet weak var matchTargetSwitchOutlet: UISwitch!
@IBOutlet weak var targetScoreLabel: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let VC = segue.destination as? SecondViewController {

        VC.player1CurrentScore = player1Score
        VC.player2CurrentScore = player2Score
        VC.player3CurrentScore = player3Score
        VC.player4CurrentScore = player4Score
    }
}

第二个视图控制器

class SecondViewController: UIViewController {

@IBOutlet weak var CurrentRoundScoreLabel: UILabel!

@IBOutlet weak var CurrentPlayerScoreLabel: UILabel!

var player1CurrentScore = 1
var player2CurrentScore = 1
var player3CurrentScore = 1
var player4CurrentScore = 1


override func viewDidLoad() {
    super.viewDidLoad()

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let VC = segue.destination as? ThirdViewController {

        VC.player1ScoreLabel.text = String(player1CurrentScore)
        VC.player2ScoreLabel.text = String(player2CurrentScore)
        VC.player3ScoreLabel.text = String(player3CurrentScore)
        VC.player4ScoreLabel.text = String(player4CurrentScore)

    }
}

第三视图控制器

class ThirdViewController: UIViewController {

@IBOutlet var player1ScoreLabel: UILabel!
@IBOutlet var player2ScoreLabel: UILabel!
@IBOutlet var player3ScoreLabel: UILabel!
@IBOutlet var player4ScoreLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
}

}

无论我尝试使用UILabel.text做什么,它都显示为nil

我完全感到沮丧,并且我肯定因为沮丧而错过了一些简单的事情,请有人帮助我。

1 个答案:

答案 0 :(得分:0)

当您通过3个不同的对象传递数据时,这是一种低效的方法。但是,继续使用此方法,问题是尚未在

内部创建标签
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let VC = segue.destination as? ThirdViewController {

        VC.player1ScoreLabel.text = String(player1CurrentScore)
        VC.player2ScoreLabel.text = String(player2CurrentScore)
        VC.player3ScoreLabel.text = String(player3CurrentScore)
        VC.player4ScoreLabel.text = String(player4CurrentScore)

    }
}

请参见,标签尚未创建。因此,您要在未初始化的text上设置UILabel。因此,您需要为ThirdViewController内的标签创建变量。

第三视图控制器

class ThirdViewController: UIViewController {

    @IBOutlet var player1ScoreLabel: UILabel!
    @IBOutlet var player2ScoreLabel: UILabel!
    @IBOutlet var player3ScoreLabel: UILabel!
    @IBOutlet var player4ScoreLabel: UILabel!

    var score0:Int!
    var score1:Int!
    var score2:Int!
    var score3:Int!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.player1ScoreLabel.text = String(score0)
        self.player2ScoreLabel.text = String(score1)
        self.player3ScoreLabel.text = String(score2)
        self.player4ScoreLabel.text = String(score3)
    }
}

并在SecondViewController中更改序号

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let VC = segue.destination as? ThirdViewController {

        VC.score0 = player1CurrentScore
        VC.score1 = player2CurrentScore
        VC.score2 = player3CurrentScore
        VC.score3 = player4CurrentScore

    }
}

另一种方式:

让我们创建一个名为Game的单例。在此范围内(假设您只有4个玩家),我们可以创建4个不变的玩家。这使我们可以在一个位置创建玩家实例,并在必要时调用它们。

注意:单例很容易被滥用。

https://cocoacasts.com/what-is-a-singleton-and-how-to-create-one-in-swift https://cocoacasts.com/are-singletons-bad/

class Game {

    static var score0:Int = 0
    static var score1:Int = 0
    static var score2:Int = 0
    static var score2:Int = 0

}        

然后,在代码中的任何地方都可以访问Game.score0,Game.score1。

注意:

我会提醒您非常小心地使用单例。您不希望所有内容都具有公共访问权限。您需要确定这是否对您有利。干杯。