Search code examples
cocoamodal-dialognsprogressindicator

NSProgressIndicator on Modal Sheet Doesn't Animate


My main window controller has a toolbar item that triggers the presentation of a modal sheet. The sheet is supposed to display the progress of a lengthy, asynchronous process (e.g., sync local data with a server).

However, I can not get the (indeterminate) progress indicator to animate.

This is the action that triggers the modal sheet:

var syncProgressWindowController: SyncProgressWindowController!

// ...

@IBAction func syncWithServer(_ sender: AnyObject) {

    // (Actual HTTP code not implemented)

    syncProgressWindowController = SyncProgressWindowController()
    syncProgressWindowController.loadWindow()

    guard let modalWindow = syncProgressWindowController.window else {
        return
    }

    self.window?.beginSheet(modalWindow, completionHandler: { (response) in
        // THIS GETS EXECUTED. 
        // However, the code below has no effect:   

        self.syncProgressWindowController.progressIndicator.startAnimation(self)

        // self.syncProgressWindowController.progressIndicator is 
        // NOT nil, despite windowDidLoad() not being called
        // (see below)
    })
}

The modal sheet window controller (class SyncProgressWindowController above) is defined like this:

@IBOutlet weak var progressIndicator: NSProgressIndicator!


convenience init() {
    self.init(windowNibName: "SyncProgressWindow")
}

override func windowDidLoad() {
    super.windowDidLoad()
    // Breakpoints here don't work, logs don't print to the console.
    // Not called? But outlet _is_ set (see above).
}

The xib file (SyncProgressWindow.xib) has:

  • File's Owner Identity/Class set to "SyncProgressWindowController"
  • Window has New Referencing Outlet to File's Owner's window
  • Window has delegate outlet wired to "File's Owner" (just in case - but delegate methods don't seem to get called either).
  • Window has "Visible at Launch" unchecked (and is therefore displayed modally with no problems).
  • Progress has New Referencing Outlet wired to File's Owner's progressIndicator.

However:

  1. SyncProgressWindowController's windowDidLoad() does not get called (Execution does not stop at breakpoints there and logs aren't printed).
  2. Despite that, the property/outlet progressIndicator is set somehow, because the app does not crash when I attempt to animate it, with code like this:
    self.syncProgressWindowController.progressIndicator.startAnimation(self)

What am I missing?


Solution

  • completionHandler will be fired when you close sheet by endSheet(_:returnCode:) So you start indicator before sheet will be closed.

    I'm not good in xib files, but when i disabled row with loadWindow, windowDidLoad was called. I'm not sure it's right way.