Obtaining a View Controller Reference

596 views Asked by At

I read quite a few questions and answers no this problem. Some are for Ojective C. Some are for iOS. The ones that were close to what I need didn't work.

I've set up a protocol for delegation. It doesn't work. The problem is that delegate variable isn't set. I need the reference to an active controller.

Delegator

protocol SwitchTabDelegate: class {
  func selectTab(tab: Int)
}

class ViewController: NSViewController {

  weak var delegate: SwitchTabDelegate?

  override func viewDidLoad() {
    super.viewDidLoad()
  }

  @IBAction func selectCompositions(_ sender: NSButton) {

    if let delegate = self.delegate {
      delegate.selectTab(tab: 2)
    }
    else {
      print("self.delegate is nil")
    }
    print("delegate called")
  }
}

Delegatee

class TabViewController: NSTabViewController, SwitchTabDelegate {

  var viewController : ViewController?;

  override func viewDidLoad() {
    super.viewDidLoad()
    //viewController = storyboard?.instantiateController(withIdentifier: "viewController") as? ViewController
   // viewController?.delegate = self
  // print(viewController)
  }

  func selectTab(tab: Int) {
    print("In the delegate")
    switchToDataTab()
  }

  func switchToDataTab() {
    Timer.scheduledTimer(timeInterval: 0.2, target: self,
        selector: #selector(switchToDataTabCont),
        userInfo: nil, repeats: false)
  }

  func switchToDataTabCont(){
    self.selectedTabViewItemIndex = 2
  }
}

The delegatee is the main NSViewContoller. On the storyboard, it contains two buttons and a Container view controller. Embedded in the container view controller is the TabViewController, the delegatee. You can see in the delegatee where I tried to get a reference. It does get a reference, presumably to the newly instantiated instance. I need a reference to the original view controller that was spun up when the application started.

Answer

I added the following code to the delegator:

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {

  let controller = segue.destinationController as! TabViewController
  self.delegate = controller as SwitchTabDelegate
 }

That's not how it should work following the design pattern. The delegator should have no knowledge of the delegatee. I've spent way too much time on this issue so a hack is going to do.

1

There are 1 answers

2
retainCount On BEST ANSWER

When using storyboards, you want to "push" references to children when they are created vs. pulling them from an upstream controller. This is what -prepareForSegue:sender: is used for.