简体   繁体   中英

Using variables from one View Controller in another

I am following a Udemy tutorial on app development, and worked on a Tic Tac Toe game. I am absolutely loving my time with app development and have coded in several other languages outside of swift. My issue comes in when I allow the user to enter his/her name on one screen (shown below in first image) and when the "Play" button is hit, it saves the names typed into the text fields and concatenates it with "'s turn" on the second view controller in order to state which users turn it is. At the end of the game I also wish to display who the winner is by name. If I figure out how to use the user data from the first view controller in the second I will be able to figure the coding part out on my own. I have referenced: Accessing variables from another ViewController in Swift but I still am not understanding how this works or if it the same problem I am having. I will attach a picture of both view controllers below and their code. Thanks for the help in advance!

both view controllers

code to the view controller that takes user input:

// 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)
    }

}

code to the actual game:

// 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.
    }

}

also note that I had tried saving the data on the users device using:

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

I also saw a similar question on here that stated that variables are public and can be used throughout, my issue is I want the names saved when the button is pressed and declaring them public/static there does not work either.

I'd suggest a 3rd class to abstract Player info and make it Singleton. Something like this:

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")
        }
    }
}

And access/set same like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM