53

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

sudo make install
  • 5,629
  • 3
  • 36
  • 48
AJ.
  • 1,226
  • 1
  • 16
  • 21

5 Answers5

115

You can use [[self view] window]

Tom Dalling
  • 23,305
  • 6
  • 62
  • 80
  • I have tried this in the past - Xcode returns a Method '-view' not found (return type defaults to 'id') error – AJ. Apr 19 '11 at 18:33
  • 3
    If `self` doesn't have a `view` method, then it's not an `NSViewController`. – Tom Dalling Apr 20 '11 at 02:34
  • Thanks Tom - that's my issue! I have a controller for the sheet that is instantiated by a subclassed NSViewController. Trouble is my sheet controller is subclassed from NSObject. To fix the issue I am now getting the window from my subclassed viewController using [[self view] window] and sending this to my sheet controller. Previously I was trying to get the window from my sheet controller – AJ. Apr 28 '11 at 03:19
  • 4
    @AJ @TomDalling my `[self view]` returns but `[[self view] window]` returns null, not sure what to do now. – Jason Murray Mar 16 '15 at 00:21
  • I have the same issue as Jason – real 19 Sep 13 '15 at 16:51
  • @Ethan It means that the view isn't in a window. The view either hasn't been added yet, or it has been removed. – Tom Dalling Oct 15 '15 at 10:39
  • 4
    @JasonMurray have you tried calling self.view.window in viewWillAppear of the NSViewController? – Riskov Feb 11 '16 at 16:16
42

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().

pkamb
  • 33,281
  • 23
  • 160
  • 191
Tim Closs
  • 536
  • 4
  • 6
2

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
    }

}
marcprux
  • 9,845
  • 3
  • 55
  • 72
1

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

JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

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
}
user1105951
  • 2,259
  • 2
  • 34
  • 55