简体   繁体   中英

How to pass variables from one View Controller to another in WatchOS 2 & Swift

I am having a lot of problems trying to get a couple of variables from one View Controller to the next. How can I do it properly? Here's my code below. This is the view controller where I want to be able to send the variables RedScoreW and BlueScoreW to the next window. I am asking on HOW TO DO THIS using SWIFT language and specially for WATCHOS apps.

class InterfaceController2: WKInterfaceController {

    var RedScoreW = 0
    var BlueScoreW = 0


    @IBOutlet var WatchRedScoreLabel: WKInterfaceLabel!
    @IBOutlet var WatchBlueScoreLabel: WKInterfaceLabel!

    @IBAction func RedScorePlus() {
        if RedScoreW == 999 {
            RedScoreW = 0
            WatchRedScoreLabel.setText("0")
        }else {
            RedScoreW += 1
            WatchRedScoreLabel.setText(String(RedScoreW))
        }
    }
    @IBAction func RedScoreMinus() {
        if RedScoreW == 0 {
            RedScoreW = 999
            WatchRedScoreLabel.setText("999")
        }
        else {
        RedScoreW -= 1
        WatchRedScoreLabel.setText(String(RedScoreW))
        }
    }

    @IBAction func BlueScorePlus() {
        if BlueScoreW == 999 {
            BlueScoreW = 0
            WatchBlueScoreLabel.setText("0")
        } else{
        BlueScoreW += 1
        WatchBlueScoreLabel.setText(String(BlueScoreW))
        }
    }

    @IBAction func BlueScoreMinus() {
        if BlueScoreW == 0 {
            BlueScoreW = 999
            WatchBlueScoreLabel.setText("999")
        }
        else {
            BlueScoreW -= 1
            WatchBlueScoreLabel.setText(String(BlueScoreW))
        }
    }

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)

        WatchRedScoreLabel.setText(String(RedScoreW))
        WatchBlueScoreLabel.setText(String(BlueScoreW))


        // Configure interface objects here.
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }


}

And this is the Destination View Controller where I want to be able to use RedScoreW and BlueScoreW variables.

class InterfaceController3: WKInterfaceController {


    @IBOutlet var finalRedScoreLabel: WKInterfaceLabel!

    @IBOutlet var finalBlueScoreLabel: WKInterfaceLabel!

    @IBAction func DoneAndResetButton() {
        self.popToRootController()
    }

    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)


        // Configure interface objects here.
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }

}

* EDIT *

I am trying to do it this way, this is the code where I send it, check:

  @IBAction func FinishButtonPushVariables() {

        arrayofScores[0] = RedScoreW
        arrayofScores[1] = BlueScoreW

        pushControllerWithName("LastScreen", context: arrayofScores)

    }

And this is where I receive it... and it doesn't work. LOL

  @IBOutlet var finalRedScoreLabel: WKInterfaceLabel!

    @IBOutlet var finalBlueScoreLabel: WKInterfaceLabel!

    @IBAction func DoneAndResetButton() {
        self.popToRootController()
    }


    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)

        let finalarrayofScores = context as? InterfaceController2

        finalBlueScoreLabel.setText(String(finalarrayofScores!.arrayofScores[1]))
        finalRedScoreLabel.setText(String(finalarrayofScores!.arrayofScores[0]))



        // Configure interface objects here.
    }

In iOS apps, we use prepareForSegue to do this. On watchOS apps, we use contextForSegueWithIdentifier to pass a context from one interfaceController to another.

Here is a link to the class reference that will detail more about this. But here are the basics:

There are two different methods that can be used. One is for going from one interface controller to another:

func contextForSegueWithIdentifier(_ segueIdentifier: String) -> AnyObject?

The other is for going from a one interface controller to another when a row in a table is tapped :

func contextForSegueWithIdentifier(_ segueIdentifier: String, inTable table: WKInterfaceTable, rowIndex rowIndex: Int) -> AnyObject?

So one of these two methods will go in the interfaceController that is sending the context, and you will receive that context in the awakeWithContext method of the receiving interfaceController.

Here is a link to a tutorial that will show an application of this process.

EDIT

Here is a specific solution to your problem.

In the interface controller where you send it, put this code:

override func contextForSegueWithIdentifier(segueIdentifier: String) -> AnyObject? {
    arrayofScores[0] = RedScoreW
    arrayofScores[1] = BlueScoreW
    return arrayOfScores
}

Then in your destination interface controller, put this code:

override func awakeWithContext(context: AnyObject?) {
    super.awakeWithContext(context)
    let finalArrayOfScores = context as? [Int]

    if let f = finalArrayOfScores {
        finalBlueScoreLabel.setText(String(f[1]))
        finalRedScoreLabel.setText(String(f[0]))
    }

}

You need to set up variables to hold your variable first.

class YourSecondViewController: UIViewController {
    var yourVariable:Double?
}

Then have your button trigger your custom segue. Use your variable as the argument for sender.

class YourFirstViewController: UIViewController {
    @IBAction func buttonTapped(sender: AnyObject) {
        self.performSegueWithIdentifier("segue", sender: yourVariable)
    }
}

Then pass the sender data by overriding the prepareForSegue method:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier = "segue") {
        let secondViewController = segue.destinationViewController as YourSecondViewController
        let yourVariable = sender as Double
        secondViewController.duration = yourVariable
    }
}

I guess your problem is that you are passing an array to the context and you cast it as WKIntefaceController. Try replacing this line

 let finalarrayofScores = context as? InterfaceController2

by

let finalarrayofScores = context as? [Int]

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