【问题标题】:Using variables from one View Controller in another在另一个视图控制器中使用来自一个视图控制器的变量
【发布时间】:2018-06-29 01:46:40
【问题描述】:

我正在学习有关应用程序开发的 Udemy 教程,并且从事过井字游戏。我非常喜欢我的应用程序开发时间,并且在 swift 之外用其他几种语言编写过代码。当我允许用户在一个屏幕上输入他/她的名字(如下图所示)并且点击“播放”按钮时,我的问题出现了,它会保存输入到文本字段中的名称并将其与“' s turn" 在第二个视图控制器上,以说明哪个用户打开了它。在游戏结束时,我还希望显示获胜者的姓名。如果我在第二个中弄清楚如何使用来自第一个视图控制器的用户数据,我将能够自己弄清楚编码部分。我参考过:Accessing variables from another ViewController in Swift 但我仍然不明白这是如何工作的,或者它是否与我遇到的问题相同。我将附上下面两个视图控制器的图片及其代码。我在这里先向您的帮助表示感谢!

两个视图控制器

获取用户输入的视图控制器的代码:

// MainViewController.swift
// Tic Tac Toe
// main menu/player select

import UIKit

class MainViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var playerOneName: UITextField!
    @IBOutlet weak var playerTwoName: UITextField!

    @IBAction func play(_ sender: Any) {

    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        return true
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

}

实际游戏的代码:

// ViewController.swift
// Tic Tac Toe
// View Controller game screen

import UIKit

class ViewController: UIViewController {

    // 1 is noughts, 2 is crosses
    var activePlayer:Int = 1
    var activeGame:Bool = true
    @IBOutlet weak var turnLabel: UILabel!
    var gameState = [0, 0, 0, 0, 0, 0, 0, 0, 0] // 0 = empty, 1 = nought, 2 = cross
    let winningCombination = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8],[0, 4, 8], [2, 4, 6]]

    @IBAction func buttonPressed(_ sender: AnyObject) {
        let activePosition = sender.tag - 1

        if gameState[activePosition] == 0  && activeGame{
            gameState[activePosition] = activePlayer

            if activePlayer == 1 {
                (sender).setImage(UIImage(named: "nought.png"), for: [])
                activePlayer = 2
            } else {
                (sender).setImage(UIImage(named: "cross.png"), for: [])
                activePlayer = 1
            }

            for combination in winningCombination {
                if gameState[combination[0]] != 0 && gameState[combination[0]] == gameState[combination[1]] && gameState[combination[1]] == gameState[combination[2]] {
                    // We have a winner!
                    activeGame = false
                    print(gameState[combination[0]])
                }
            }
        }// the spot will only be taken by the player if it is not taken yet

    }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

还请注意,我曾尝试使用以下方法将数据保存在用户设备上:

UserDefaults.standard.set(playerOneName.text forKey: "playerone")

我在这里也看到了一个类似的问题,指出变量是公共的并且可以在整个过程中使用,我的问题是我希望在按下按钮时保存名称并将它们声明为 public/static 也不起作用。

【问题讨论】:

  • 你究竟需要什么来公开或只为两个 vc 存储价值?
  • @PravinTate 对你的问题有点困惑,但我想保存玩家在第一个 VC 上输入的两个名称,并在第二个中使用它们。如果您还需要解释,请告诉我。
  • 因此,在第一个 vc 中获得两个玩家名称并点击播放按钮后,创建一个使用数组存储两个玩家名称的模式,并为第二个 vc 编写 init 方法并将其传递给该模式。
  • @PravinTate 好的,这一切对我来说都很有意义,但是 init 方法。你知道什么我可以熟悉这个来使用它吗?顺便感谢您的帮助!
  • 检查下面我试图解释给你的答案。

标签: ios swift swift4 xcode9


【解决方案1】:

我建议使用第三类来抽象玩家信息并使其成为单例。像这样的:

class Players {
    static let shared = Players()

    var one: String {
        get {
            return UserDefaults.standard.object(forKey: "playerone") as? String ?? ""
        }
        set(newValue) {
            UserDefaults.standard.set(newValue, forKey: "playerone")
        }
    }
}

并像这样访问/设置:

Players.shared.one = "Name one"
print(Players.shared.one)

【讨论】:

  • 这个类会在主菜单的 VC 中,还是在游戏中?如果它像我假设的那样在主菜单中,我将能够像您所说的那样访问它:Players.shared.one = "Name one" print(Players.shared.one)?
  • 您可以在项目中的任何位置声明/访问此类:VC 类的新文件或文件结尾
  • 也只是一个小问题,因为我还是新手,是否应该在应用开发中也使用 setter/getter 方法?
  • 非常感谢!我会处理这个。这将有助于解决未来的很多问题,很高兴知道。非常感谢你们俩的帮助!
  • @JeremyMcArthur 您可以在任何您认为可能有帮助的地方使用 getter/setter。其他没有限制
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多