4

I'm trying to create a macOS app like Photos.app. The NSWindowController has a toolbar with a segmented control. When you tap on the segmented control, it changes out the the NSViewController within the NSWindowController.

Example of Apple Photos.app.

What I have so far is an NSWindowController with an NSViewController. I have subclassed NSWindowController where I have the method that gets called whenever the user taps on the segmented control.

Essentially, whatever segment is clicked, it will instantiate the view controller that is needed and set it to the NSWindowController's contentViewController property.

enter image description here

Is this the correct way of doing it?

Also, the NSWindowController, I am thinking, should have properties for each of the NSViewControllers it can switch to that get lazy loaded (loaded when the user taps them and they get held around to be re-used to prevent re-initializing).

Code:

import Cocoa

class MainWindowController: NSWindowController
{
    var secondaryViewController:NSViewController?

    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.
    }

    @IBAction func segmentedControlDidChange(_ sender: NSSegmentedControl)
    {
        print("Index: \(sender.selectedSegment)")

        if sender.selectedSegment == 3 {
            if secondaryViewController == nil {
                let viewController = storyboard?.instantiateController(withIdentifier: "SecondaryViewController") as! NSViewController
                secondaryViewController = viewController
            }

            self.window?.contentViewController = self.secondaryViewController
        }
    }
}

I'm new to macOS development, however, I've been doing iOS for quite some time. If there is a better way, I'd like to know about it. Thanks!!!

Mario A Guzman
  • 3,483
  • 4
  • 27
  • 36
  • You could also consider using NSTabViewController. – jtbandes Jun 04 '17 at 18:23
  • @jtbandes This is true but I'm trying to keep the consistent look of other macOS applications by Apple such as Photos, Notes, and Maps. I need the segmented control to remain in the toolbar alongside other things like search bars and buttons. Thank you for your input! – Mario A Guzman Jun 04 '17 at 18:26
  • NSTabViewController can be used without visible tabs, just to handle the switching between content VCs. – jtbandes Jun 04 '17 at 18:26

1 Answers1

2

to move the tab/segmented-control to the titlebar, you need:

  1. add toolbar to window, and add the controls to the toolbar,
  2. hide title:

    class TopLevelWindowController: NSWindowController {
    
      override func windowDidLoad() {
        super.windowDidLoad()
    
        if let window = window {
    
            // reminder like style
            // window.titlebarAppearsTransparent = true
            window.titleVisibility = .hidden
            // window.styleMask.insert(.fullSizeContentView)
        }
      }
    }
    
  3. now, toolbar will be merged into the top bar position.

hedzr
  • 155
  • 2
  • 7