NSWiewController

I'm developing an application with a NSSplitView in the main NSWindowController which is organized like that:


a menu on the left panel, which contains an outlineView with many choices and a detailView on the right panel which corresponds to the item choosen in the left panel.


In the main NSWindowController, I have a toolbar with Buttons (that's the important point)


Then I click on an item in the left panel, I have the following action:


func outlineViewSelectionDidChange(_ notification: Notification) {
        let outline = notification.object as! NSOutlineView
        let item = outline.item(atRow: outline.selectedRow)
        if item is MenuSocietes {
            if vc != nil {
                splitView.removeArrangedSubview((splitView?.subviews[1])!)
                vc = nil
            }
            vc = societesController()
            contentViewController?.presentAsModalWindow(vc)
            if splitView.subviews.count > 1 {
                splitView.removeArrangedSubview((splitView?.subviews[1])!)
            }
            splitView.addSubview(vc.view)
        } if item is MenuImmeuble {
            if vc != nil {
                splitView.removeArrangedSubview((splitView?.subviews[1])!)
                vc = nil
            }
            vc = immeubleController((item as! MenuImmeuble).id)
            contentViewController?.presentAsModalWindow(vc)
            if splitView.subviews.count > 1 {
                splitView.removeArrangedSubview((splitView?.subviews[1])!)
            }
            splitView.addSubview(vc.view)
        } else {
            if vc != nil {
                splitView.removeArrangedSubview((splitView?.subviews[1])!)
                vc = nil
            }
        }
    }

Of course this is just a example (a little dirty, I know).

societesController and immeubleController are NSViewControllers.


Now I want my detailView (in the above code, societesController or immeubleController) to interact with the NSToolbar of the main NSWindowController.


It would be easy to pass this toolbar as a parameter in the init code of my details NSViewController, but I'm not sure it's the finest way.


I try to find, in my viewControllers (societesController and immeubleController) the ancestor, doing something like this:


var _parent = presentingViewController
        while _parent != nil {
            Swift.print(_parent?.className)
            _parent = _parent!.parent
        }

the first line return nil as _parent. Am I missing something?

Accepted Reply

You are right, I chosse the first

because one thing I didn't told is that my application is document based so I can have multiple splitview and multiple toolbars.

That"s why I was looking for the ancestor


Thank's

Replies

In such case you can either:


- use delegates

Define a protocol, SplitCoordination (just to give a name) with a func actionOnToolBar

MasterView would conform to SplitCoordination and implement the action

Define a deletae in DetailView

var splitDelegate : SplitCoordination?

On transitioning to DetailView, set the delegate

detailView.splitDelegate = self

In Detail, where you need, invoke

splitDelegate?.actionOnToolBar() // With relevant parameters


- post notifications

Have Master subscribe to a notification

Post notification from Detail

On receiving notification, Master will do what is needed ; it can even pass data to detail through another notification in userInfo.

func post(name aName: NSNotification.Name, object anObject: Any?, userInfo aUserInfo: [AnyHashable : Any]? = nil)


- Define global var for Master and Detail instances and use them directly.


Seems the first should be preferred in this case.

You are right, I chosse the first

because one thing I didn't told is that my application is document based so I can have multiple splitview and multiple toolbars.

That"s why I was looking for the ancestor


Thank's

So, was the proposed solution the correct answer ?


That was the advice.