1

I'm quite new to programming in general - and to Swift in particular - but there's one thing I've been pounding my head on recently.

I'm trying to access a variable in a 'parent' class - but I can't work out how to get there.

I've already looked at other posts that seem to cover the same thing - Access variable in different class - Swift , How to create a global variable? , Access variable in different class - Swift and Pass variables from one ViewController to another in Swift - but none of them seem to do exactly what I want.

I'm wanting to be able to have a window of Preference settings, which I can set and have apply to variables in my 'main' class - but I can't see how to pass the variables from the Preferences window up to the 'main' class.

Here's an example in which I've defined an NSTextField on my first ViewController, which I want to be able to modify in my second ViewController and have it update in the first. My actual application will probably need many such instances, in order to provide a full set of modifiable preferences.

//  ViewController.swift

import Cocoa


class ViewController: NSViewController {


lazy var sheet2ViewController: NSViewController = {
    return self.storyboard!.instantiateControllerWithIdentifier("sheet2") as! NSViewController}()


@IBAction func openPanel(sender: AnyObject) {
    displaySheet()
}


@IBOutlet weak var textField: NSTextField!


var textString : String = "" {
    didSet {
        textField.stringValue = textString
    }
}


func displaySheet() {

    self.presentViewControllerAsSheet(sheet2ViewController)

}



override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

override var representedObject: AnyObject? {
    didSet {
    // Update the view, if already loaded.
    }
}


}



//  SecondViewController.swift

import Cocoa

class SecondViewController: NSViewController {

@IBOutlet weak var textField2: NSTextField!


@IBAction func closeButton(sender: AnyObject) {
    ???.textString = textField2.stringValue // How to address the ViewController variable here?
    self.dismissController(self)

}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
}

}

As you see, the issue I have is in the closeButton function in the SecondViewController class - how to pass the value back up to the textString variable in the ViewController class?

I've been looking at delegation and NSNotificationCenter - but I really don't know if I'm barking up the right trees here - it feels like I'm going to have to implement something much more complicated than I would expect for such a (seemingly) simple requirement.

Any suggestions very welcome - thanks.

2 Answers 2

0

In an OSX storyboard NSViewController has a property presentingViewController which represents the parent view controller.

In SecondViewController you can refer to the presenting controller with

let parentViewController = presentingViewController as! ViewController
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Vadian - but when I try this, I get the error: 'Instance member 'presentingViewController' cannot be used on type 'SecondViewController''.
You are calling the method on the type but you have to call it on the instance, the line must be inside a method.
@vadian self.presentingViewController as the name suggests showing the view itself not the parent.
Actually the presented controller is the current controller. The presenting controller is in fact the parent view controller.
0

Try using delegates and protocols. When you create the child you set its delegate to be the parent. One of the delegate methods can have a parameter that the child can set and the parent(or the class that implements the delegate) can read.

A small example:

protocol MyProtocol {
    func turnedOn(val:Bool) -> Void
}

class Headlights {
    var delegate:MyProtocol?

    func test1() -> Void {
        if let del = delegate {
            del.turnedOn(true)
        }
    }
}

class Car:MyProtocol {
    var lamp:Headlights

    init() {
        lamp = Headlights()
        lamp.delegate = self
    }

    func turnedOn(val:Bool) -> Void {

    }
}

1 Comment

Thanks Horatiu. I think I'm going to need to spend more time studying protocols and delegation - it just hasn't clicked for me yet. In the meantime, Vadian's answer gets me what I need to do for the moment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.