8 Replies
      Latest reply on Feb 13, 2019 10:08 AM by john daniel
      Pendragon Level 1 Level 1 (0 points)

        With an NSOpenPanel, is there a way to style as sheet & not a floating window, without using beginSheetModal ?

        • Re: NSOpenPanel style as sheet not floating window ?
          john daniel Level 3 Level 3 (320 points)

          I doubt it. The idea is that the panel is used to open a document, so how can you already have a document open to use with a sheet? Also, sandboxed apps do some clevery trickery to provide a sandbox escape and that might prevent the sheet from being attached to anything inside your process.

          • Re: NSOpenPanel style as sheet not floating window ?
            QuinceyMorris Level 8 Level 8 (5,880 points)

            What does "without using beginSheetModal" mean? That is the way to present an open or save panel as a sheet, necessarily attached to a window. What are you actually trying to do, if not present the sheet on an underlying window?

             

            >>I don't see how you are going to get the sheet to work as a sheet when it is in a different process as in the sandbox.

             

            This is just how it works. There's a bit of fakery going on behind the scenes (in macOS frameworks) that presents the content of the panel (provided by a separate process) on top of a window or sheet of your process, so that it looks like the content is inside your window or sheet.

              • Re: NSOpenPanel style as sheet not floating window ?
                Pendragon Level 1 Level 1 (0 points)

                Running beginSheetModal works as expected displaying a sheet attached to the main window with open & cancel options, but getting a result as it returns as void is the problem. When not using a sheet I run .runModal() set as a variable then just then switch it's case for the Modal response which I can then use for a return result.

                 

                If I set up a case in the completionHandler switching option I can't return anything because it's void.

                  • Re: NSOpenPanel style as sheet not floating window ?
                    QuinceyMorris Level 8 Level 8 (5,880 points)

                    Ah, I see.

                     

                    The difficulty you've run into is not essentially about open panels, but is the difference between a synchronous API (runModal) and an asynchronous API (beginSheetModal). Instead of this:

                     

                    result = someSynchronousAPI()
                    doSomething(with: result)
                    return

                     

                    you'd do this:

                     

                    someAsynchronousAPI() {
                        result in
                        doSomething(with: result)
                    }
                    return

                     

                    In the first case, you return after completing the synchronous code and continue with the rest of your code. In the second case, you return after initiating the asynchronous code but don't immediately continue with your code. When the asynchronous completion handler is called, you continue with the rest of your code.

                     

                    It's an important pattern to learn in "modern" programming, and it's not really hard — once you get your brain wrapped around it.

                     

                    FWIW, Swift will eventually be enhanced to provide syntax that improves the readability of asynchronous code (something vaguely like C#'s async/await), but it'll be a while before that arrives. For the present, completion handlers are the way to go.

                    • Re: NSOpenPanel style as sheet not floating window ?
                      john daniel Level 3 Level 3 (320 points)

                      It looks like QuincyMorris is correct. I've never used an NSOpenPanel as a sheet, but it should work. There is a sheet method in NSSavePanel which should be accessible from NSOpenPanel.

                       

                      func beginSheetModal(for window: NSWindow, completionHandler handler: @escaping (NSApplication.ModalResponse) -> Void)

                       

                       

                      It makes sense to save as a sheet since the document is already open. It would also make sense to use this method to add additional content to an already open document.