9 Replies
      Latest reply on Nov 4, 2019 4:53 AM by Claude31
      narcisfromgirona Level 1 Level 1 (0 points)

        I want a window to not appear at launch to be able to control later how and where. In storyboard I select Window / Attributes and deselect "Visible At Launch" but it still appears. I even tried a new project with no code and just one window and it happens the same. Am I missing anything? Why is it not working? How to hide the window at the beginning?

        • Re: Window not Visible At Launch
          Claude31 Level 8 Level 8 (7,245 points)

          I tested in a project and the window doesnot show if 'Visible At Launch' is turned off.

           

          Where is the window ? In the MainMenu.xib ?

          Or are you using a document based app ?

           

          Try an option clean Build Folder, in case.

           

          Which version of XCode ?

          Which version of MacOS ?

            • Re: Window not Visible At Launch
              narcisfromgirona Level 1 Level 1 (0 points)

              I do New Project > macOS > App > User Interface Storyboard

              I go to Main.storyboard > Attributes > Select Window (Inside Window Controller) and check that Visible At Launch is not selected by default

              I click the play button and a window appears

               

              I have "clean build folder" and try again. It appears.

               

              MacOS 10.14.6

              Xcode 11.1

               

                • Re: Window not Visible At Launch
                  Claude31 Level 8 Level 8 (7,245 points)

                  You have defined with Storyboard.

                   

                  And your windowController is declared as initial controller.

                  That's why it is forced visible.

                   

                  If you create a new project, and select xib instead of storyboard, you will get only a main menu and a window (may be anywhere in the canvas, take care to find it).

                  Now, you can make it invisible at launch.

                   

                  You can stay with storyboard, remove the initial controller arrow, window will not be visible.

                  But you cannot then ask to make it visible at launch.

                   

                  Conclusion, in storyboard, initialController and visible at launch are linked together (don(t know where it's documented).

                    • Re: Window not Visible At Launch
                      narcisfromgirona Level 1 Level 1 (0 points)

                      Thank you very much!. I had no idea. I was completely lost. I understand your explanation on how to make it not visible at launch. But  I still do not understand how it works as a whole. How to make it appear later?. I have been searching for tutorials, or anywhere that could explain the whole picture and I cannot find it.

                       

                      What I try to do is to control the position and size of the window from the beginning. I tried that on the viewDidLoad. I give some seconds to load the page. (without that I could not see the page)

                              DispatchQueue.main.asyncAfter(deadline: .now() + 3.0){

                                  self.view.window?.setFrame(NSRect(x:10,y:10,width:200,height:100), display: true)

                              }

                       

                      This works in regular storyboard but the window appears and then reposition. A strange effect. That is why I wanted to hide on the beginning. If I use xip, I have no place to put the code to open the window later. If I use the storyboard and delete the arrow, that code does not work, gives me an error. Sorry, I do not know where to go to learn. Thank you in any case.

                        • Re: Window not Visible At Launch
                          Claude31 Level 8 Level 8 (7,245 points)

                          What scheme have you selected ? xib or Storyboard ?

                           

                          With a storyboard, here is a solution.

                           

                          Define a class for the window.

                           

                          Outside of class definition create a var for the controller

                           

                          import Cocoa
                          
                          var firstController : NSWindowController?
                          
                          class FirstWindowController: NSWindowController, NSWindowDelegate {
                          
                              override func windowDidLoad() {
                                  super.windowDidLoad()
                                 
                                  firstController = self
                              }
                          
                          }

                           

                           

                          The windowController is set to class FirstWindowController.

                           

                          In IB, insert a MenuItem, 'Show', for instance aa first item of File menu.

                          Control drag from this item to AppDelegate, to create an IBAction

                           

                          import Cocoa
                          
                          @NSApplicationMain
                          class AppDelegate: NSObject, NSApplicationDelegate {
                          
                          
                              @IBAction func showWindow(_ sender: NSMenuItem) {
                                  firstController?.showWindow(self)
                              }
                             
                              func applicationDidFinishLaunching(_ aNotification: Notification) {
                                  // Insert code here to initialize your application
                              }
                          
                              func applicationWillTerminate(_ aNotification: Notification) {
                                  // Insert code here to tear down your application
                              }
                          
                          }

                           

                          If the window is hidden or if you closed it, call this 'Show' menuItem to make it appear.

                          • Re: Window not Visible At Launch
                            Claude31 Level 8 Level 8 (7,245 points)

                            I had to struggle some time to get the initial view appear at the right position and size.

                             

                            Here it is for a xib (MainMenu.xib), in which a window (splashWindow) is defined and connected to its IBOutlet in AppDelegate.

                            I set the frame in appDidFinishLaunching

                             

                            class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
                            
                                @IBOutlet weak fileprivate var splashWindow : NSWindow!
                            
                                func applicationDidFinishLaunching(_ aNotification: Notification) {
                            
                                    let screen: NSScreen = NSScreen.main!
                                    let midScreenX = screen.frame.midX
                                    let posScreenY = 200
                                    let origin = CGPoint(x: midScreenX - 300, y: posScreenY) // 300: half width
                                    let size = CGSize(width: 600, height: 200)
                                    frame = NSRect(origin: origin, size: size)
                                    splashWindow.setFrame(frame, display: true)
                                 }
                            
                            }
                              • Re: Window not Visible At Launch
                                Claude31 Level 8 Level 8 (7,245 points)

                                For a Storyboard app, I did it this way (works also for xib based).

                                 

                                1. Create a subclass of NSWindow

                                 

                                2. Set the initial windowController to this class

                                 

                                3. Change the frame in windowDidBecomeMain

                                 

                                import Cocoa
                                
                                class FirstWindowController: NSWindowController, NSWindowDelegate {
                                
                                    override func windowDidLoad() {
                                        super.windowDidLoad()
                                   
                                        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
                                    }
                                   
                                    func windowDidBecomeMain(_ notification: Notification) {
                                        let newFrame = NSRect(x: 120, y: 100, width: 300, height: 200)
                                        print(#function, self.window?.frame)
                                        self.window?.setFrame(newFrame, display: true)
                                        print(#function, self.window?.frame)
                                    }
                                   
                                }

                                Note: Make sure to quit the app before running with new frame value.

                                 

                                If you do so, you may have to manage a new property for the window

                                var firstAppearance = true

                                 

                                otherwise, when you move the window, select another one and reselect it, it will return to this position.

                                 

                                So, code becomes:

                                 

                                class FirstWindowController: NSWindowController, NSWindowDelegate {
                                
                                    fileprivate var firstAppearance = true
                                
                                    override func windowDidLoad() {
                                        super.windowDidLoad()
                                
                                        // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
                                    }
                                
                                    func windowDidBecomeMain(_ notification: Notification) {
                                        if firstAppearance {
                                            let newFrame = NSRect(x: 120, y: 100, width: 300, height: 200)
                                            self.window?.setFrame(newFrame, display: true)
                                        }
                                     firstAppearance = false
                                    }