OS X - How can a NSViewController find its window?

MacosCocoaCocoa Sheet

Macos Problem Overview


I have a Document based core data app. The main document window has a number of views, each controlled by its own custom NSViewController which are switched in as necessary. I want each of these view controllers to be able to drop down a custom modal sheet from the document window. However because the views are separate and not in the MyDocument nib I cannot link the view to the document window in IB. This means that when I call

[NSApp beginSheet: sheetWindow modalForWindow: mainWindow modalDelegate: self didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) contextInfo: nil];

I’m supplying nil for mainWindow and the sheet therefore appears detached.

Any suggestions?

Many Thanks

Macos Solutions


Solution 1 - Macos

You can use [[self view] window]

Solution 2 - Macos

Indeed, it's self.view.window (Swift).

This may be nil in viewDidLoad() and viewWillAppear(), but is set properly by the time you get to viewDidAppear().

Solution 3 - Macos

One issue with the other answers (i.e., just looking at self.view.window) is that they don't take into account the case that when a view is hidden, its window property will be nil. A view might be hidden for a lot of reasons (for example, it might be in one of the unselected views in a tab view).

The following (swift) extension will provide the windowController for a NSViewController by ascending the view controller hierarchy, from which the window property may then be examined:

public extension NSViewController {
    /// Returns the window controller associated with this view controller
    var windowController: NSWindowController? {
        return ((self.isViewLoaded == false ? nil : self.view)?.window?.windowController)
            ?? self.parent?.windowController // fallback to the parent; hidden views like those in NSTabView don't have a window
    }

}

Solution 4 - Macos

If your controller can get access to the NSDocument subclass, you can use -windowForSheet

Solution 5 - Macos

more about Tim Closs answer :

-(void)viewDidAppear
{
    self.view.window.title = @"title-viewDidAppear"; //this only works when and after viewDidAppeer is called
}
-(void)viewWillDisappear
{
    self.view.window.title = @"title-viewWillDisappear"; //this only works before and when viewWillDisappear is called
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAJ.View Question on Stackoverflow
Solution 1 - MacosTom DallingView Answer on Stackoverflow
Solution 2 - MacosTim ClossView Answer on Stackoverflow
Solution 3 - MacosmarcpruxView Answer on Stackoverflow
Solution 4 - MacosJeremyPView Answer on Stackoverflow
Solution 5 - Macosuser1105951View Answer on Stackoverflow