skip to Main Content

I’m working on a controller that will allow a user to set the number of players they would like in a game. The view consists of some labels, a slider, and a button. The slider allows the user to select a value from 1-4 to select the number of players. One of those labels is set to x Player(s) Selected where x is the slider’s value rounded to the nearest Int. The button then sends the user to the game (another view) which is handled by a different View Controller (VC). I’m trying to send the number of players to the other VC but the value does not appear to be saved outside of the IBAction function.

As a possible fix, I’ve tried using an instance of GameViewController in NumberOfPlayersViewController.swift and updating the variable in setNumOfPlayers, which also did not work. Am I just missing something or is updating a variable in an IBAction not possible?

// NumberOfPlayersViewController.swift
import UIKit

class NumberOfPlayersViewCOntroller: UIViewController {
    // Default number of players
    var numOfPlayers = 1
    
    // UIObjects
    <Label here>
    <Slider here>

    @IBAction private func setNumOfPlayers(_ sender: UISlider) -> Void {
        // Get the number of players and update the label
        numOfPlayers = Int(sender.value) // Originally float, rounds the value to the nearest Int
        label.text = "(numOfPlayers) Player(s) Selected" // Updates label
        print(numOfPlayers) // Prints the rounded value
    }

    func getNumberOfPlayers() -> Int {
        return numOfPlayers // Only returns the default value of 1
// GameViewController.swift
class GameViewController:UIViewController {
    let NumberOfPlayersVC = NumberOfPlayersViewController()
    lazy var numOfPlayers = NumberOfPlayersVC.getNumberOfPlayers() // Lazy as `self` is not available 

    override func viewDidLoad() {
        super.viewDidLoad()
        print(numOfPlayers) // Prints 1
    }
}

These views that these ViewControllers handle are connected via a Seque.

2

Answers


  1. Chosen as BEST ANSWER

    A solution to my problem was actually answered in this question: Passing variables between View Controllers using a segue, but I had missed it in my search. The solution involves using performSegue and prepare in order to transfer data between views. The answer also includes what to change in order to use this method in Swift 3+.


  2. Your GameViewController creates an instance of NumberOfPlayersViewController when it’s created. In its viewDidLoad, you then fetch the value numOfPlayers. That lazy var will ask your NumberOfPlayersVC, once and only once, for the value of getNumberOfPlayers().

    If that instance of NumberOfPlayersViewController has never been displayed to the screen and had the user update its slider and tap its button, it will still return a value of 1.

    How do the 2 view controllers get displayed to the screen? When does the user get a chance to pick a value on your slider and tap the setNumOfPlayers button?

    I don’t see how that can happen between your GameViewController being initialized and its viewDidLoad method being invoked. That seems to be the problem. Your GameViewController is initialized, it creates a new instance of NumberOfPlayersViewCOntroller, its viewDidLoad method fires, its lazy var calls getNumberOfPlayers() on the NumberOfPlayersViewCOntroller, which returns 1 since that view controller hasn’t been displayed on the screen yet. The lazy var will now always have a 1 in it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search