SomeStudent
SomeStudent

Reputation: 3048

What is the correct way to use getters/setters

Salutations,

This is a follow up from my previous post (Incorrect data passed on first click of button). It was answered, but the updated edit of course occurred.

My inquiry is as follows, at the moment I have two IBActions funcs which empty, lack any sort of code, and their only purpose for existence is that they are connected to my other view controller, and as such if I remove them I have no way to differentiate between which segue should be used (My understanding is that although we can create segues between two view controllers, I do not think anything more than one would make sense (as in, how to decide which one to go with). I digress.

I tried using the following in my code before:

self.performSegue(withIdentifier: "slideTwo", sender: self);

This works well, however, it does cause double segueing. As such, I settled for the following:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        let passedPic = segue.destination as! ViewControllerTwo;

        if(segue.identifier == "slideOne") {
            passedPic.picsChosen = sLS1;
        } else {
            passedPic.picsChosen = sLS2;
        }  
    }

This works well, does what I need, but I do then have the problem of two empty IBActions:

@IBAction func slideShowOne() {

    }

    @IBAction func slideShowTwo() {

        //self.performSegue(withIdentifier: "slideTwo", sender: self);

    }

This is where I thought perhaps I could try to create a getter/setter (which swift makes far more complicated than it honestly should be). This is where I am lost.

The code looks as follows:

var picsChosen : [String] {
    set(newData) {
        for index in 0..<newData.count {
            print("Index is: ", newData[index]);
        }
        self._picsChosen = newData;
    } get {
        return self._picsChosen;
    }
}

Now, my issue is two fold. First, what is the correct way to actually access and pass values into my variable. I tried doing: myClass: ViewControllerTwo! = ViewControllerTwo();

and then use myClass.picsChosen = myArray; However, although it does appear that the data was passed successfully into my VC2, since when I loop through (inside the setter) I do see the values successfully being displayed, when I try to access picsChosen outside of that I get an index out of bounds error, in other words, the value was never associated with picsChosen. The current way I have it works well, but I want to know what is the correct way to use getters/setters, and why what I have did not work.

Cheers!

Upvotes: 2

Views: 276

Answers (1)

vacawama
vacawama

Reputation: 154583

This works well, does what I need, but I do then have the problem of two empty IBActions:

You don't need these empty @IBActions. They aren't doing anything for you. The segues are wired from the buttons in the Storyboard, so you don't need the @IBActions. If you delete the code, you also need to remove the connection from the Storyboard or your app will crash when it tries to call the removed @IBActions. To remove, control-click on the buttons in the Storyboard, and then click on the little x next to Touch Up Inside to remove the connection. Then you can delete @IBAction in your code.

if I remove them I have no way to differentiate between which segue should be used

Not true. You have two different segues wired from two different buttons. The segue's identifiers are how you differentiate between the two segues.

I tried doing: myClass: ViewControllerTwo! = ViewControllerTwo();

When using segues, the segue creates the destination viewController for you. This doesn't work because you are creating an entirely new ViewControllerTwo here. You are passing the values to this new instance, but this isn't the ViewControllerTwo that the Storyboard segue created for you.

When using segues, you should pass the data in prepare(for:sender:), just like you showed above. Get the destination ViewController and fill in the data you want to pass.

And now for the question you didn't ask:

How could I have done this using the @IBActions to trigger the segue?

  1. Remove the segues that are wired from your buttons.

  2. Wire the segue from viewController1 to viewController2. Click on the segue arrow in the Storyboard and assign the identifier slideShow.

  3. Assign unique tags to your two buttons. You can set this in Interface Builder. Give the first button tag 1, and the second button tag 2.

  4. Your buttons can share the same @IBAction:

    @IBAction func goToSlideShow(button: UIButton) {
        self.performSegue(withIdentifier: "slideShow", sender: button)
    }
    
  5. In prepare(for:sender:):

    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        let passedPic = segue.destination as! ViewControllerTwo
    
        if let button = sender as? UIButton {
            if button.tag == 1 {
                passedPic.picsChosen = sLS1
            } else if button.tag == 2 {
                passedPic.picsChosen = sLS2
            }
        }
    }
    

Upvotes: 3

Related Questions