Chaim Friedman
Chaim Friedman

Reputation: 720

@IB Action function inside of viewdidload in Swift

Is it possible to have an @IB Action function inside of viewDidLoad() ?

The action is a simple one - a Stepper that increases other label.text values accordingly. However, the values that the stepper needs to work with depend on the return content of a url - which are only known after the viewDidLoad() of course.

So I think I can't have the IBaction way up on top before the viewDidLoad(), and the error I get if I try to do my IB action inside of the viewDidLoad() is:

"Only instance methods can be declared ‘IBAction' ”

EDIT

Let me clarify myself, sorry for the confusion. I know I need an outlet to get the UIStepper values from. I have that:

    @IBOutlet weak var stepper: UIStepper!

I then have an action also connected to same UIStepper that will increase/decrease value of a label's text (new_total) accordingly:

@IBOutlet weak var new_total: UILabel!

@IBAction func step_up_pass(sender: AnyObject) {
    new_total.text = "\(Int(stepper.value))"
    }

However, I want to start out with a value (todays_price) I'm getting back from a json request and use that as a starting point, to multiply it using the stepper and put the multiplied value into the label's text.

I have a struct in a separate file that defines my object so:

struct PassengerFromOtherBus {

var fname: String?
var lname: String?
var todays_price: Int?


init(json: NSDictionary) {
    self.fname = json["fname"] as? String
    self.lname = json["lname"] as? String
    self.todays_price = json["todays_price"] as? Int
}

}

So later on in the view controller, inside of the viewDidLoad(), after connecting to the URL and then parsing it using NSJSONSerialization and a bunch of other code here (that I don't need to confuse you with) I finally have my value todays_price. So my question is, how do I get my action to use that value when it's only known inside of my viewDidLoad()? Xcode will not even let me connect the IBAction to anywhere inside the viewDidLoad function!

Upvotes: 1

Views: 1328

Answers (2)

dbmrq
dbmrq

Reputation: 1461

Just add a variable to the top of your view controller to hold the value from your json request. Then in viewDidLoad you update that variable, and then you can use it to set your label and inside the IBAction (that doesn't have to be inside viewDidLoad).

So you would do something like this:

class WhateverViewController: UIViewController {

    var todays_price: Int!

    override func viewDidLoad() {
        super.viewDidLoad()
        todays_price = // The value you got from json goes here
        new_total.text = "\(todays_price)"
    }

    @IBAction func step_up_pass(sender: AnyObject) {
        new_total.text = "\(Int(stepper.value) * todays_price)"
    }

}

Upvotes: 1

R Menke
R Menke

Reputation: 8391

This is not done with an Action but with an Outlet. Connect the Stepper from IB as an Outlet to your ViewController. Then just set the values of the Stepper in ViewDidLoad.

enter image description here

I would never go directly from a UIStepper.value to UILabel.text. Use an intermediary variable to store the value.

Do the same for the return from the JSON. By setting a didSet function on those variables you can update the UI when any of the values is updated.

class FirstViewController: UIViewController {

    var todays_price: Int = 0 {
        didSet { // didSet to trigger UI update
            myLabel.text = "\(stepperValue * todays_price)"
        }
    }

    var stepperValue : Int = 1 {
        didSet { // didSet to trigger UI update
            myLabel.text = "\(stepperValue * todays_price)"
        }
    }

    @IBOutlet weak var myStepper: UIStepper!
    @IBOutlet weak var myLabel: UILabel!

    override func viewDidLoad() {
        //
        let returnValueFromJson = 10
        todays_price = returnValueFromJson

    }

    @IBAction func stepperUpdate(sender: AnyObject) {

        stepperValue = Int(myStepper.value)

    }

}

Upvotes: 5

Related Questions