How to add tabs to documentless app on macOS?

I like to build an app in Swift 3 with Xcode 8, and it should include an Apple tab bar. This is not document based. I found out here that tabs can be enabled if I override the method @IBAction func newWindowForTab(_ sender: Any?), for example, in a window controller. To test this, I created a new project in Xcode using the storyboard, added a subclass, NSWindowControllerand assigned it in the storyboard. I then implemented

@IBAction override func newWindowForTab(_ sender: Any?) {}

and the tab bar appears when you build the application. After recovery, I noticed that the "+" -button appears only if the tab bar was not visible when the application was closed before assembly. This is mistake? How would I add new tabs?

+7
source share
3 answers

Ok here are the new files,

Appdelegate

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
}

func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
}

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
}

@IBAction func newWindowForTab(_ sender: Any?){
} // without this the + button doesn't show from start

}

ViewController

import Cocoa

class ViewController: NSViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

override var representedObject: Any? {
    didSet {
    // Update the view, if already loaded.
    }
}
}

and windowcontroller

import Cocoa

class WindowController: NSWindowController {

var subview: WindowController?

override func windowDidLoad() {
    super.windowDidLoad()
    // Implement this method to handle any initialization after your window controller window has been loaded from its nib file.
}

@IBAction override func newWindowForTab(_ sender: Any?) {

    let story = self.storyboard
    let windowVC: WindowController = story?.instantiateInitialController() as! WindowController

    self.window?.addTabbedWindow(windowVC.window!, ordered: .above)
    self.subview = windowVC

    windowVC.window?.orderFront(self.window)
    windowVC.window?.makeKey()
}

}

you need to add a menu item and connect it to FirstResponder in menu mode for newWindowForTab: action, assign a key, say cmd + t to work, this example, as soon as it adds a tab with a + button and window menu options, the tab in a new window "and" merge all windows. "You can drag the tab and drop it back, move the tabs horizontally. It looks like it works.

made with Xcode Version 8.2 beta (8C30a)

+6
source

Conceptually, this is what happens:

  • Just call NSWindow.addTabbedWindow(_:ordered:)to add a window to the native tab panels.
  • NSResponder.newWindowForTab(_:) , "+" .
  • window.tabbingMode = .preferred .

.

newWindowForTab

, @IBAction override func newWindowForTab(_ sender: Any?), NSWindow.addTabbedWindow(_:ordered:)?

  • , NSWindowController. NSWindow addTabbedWindow.
  • Xibs, AppDelegate . .
  • , , NSWindow.

, "+"

TL; DR: , - windowController. ( ).

TabManager, : https://github.com/DivineDominion/NSWindow-Tabbing

: https://christiantietze.de/posts/2019/07/nswindow-tabbing-multiple-nswindowcontroller/

, . , newWindowForTab. NSApp.sendAction , - , , NSWindowController, , AppDelegate.

, , , , , ( /). "+" , .

, @JohnV : " subview ". , . , /, ; newWindowForTab.

" " - NSWindow. newWindowForTab . .

@Peter Ahlberg, :

class WindowController: NSWindowController {

    @IBAction override func newWindowForTab(_ sender: Any?) {

        let windowController: WindowController = self.storyboard?.instantiateInitialController() as! WindowController
        let newWindow = windowController.window

        self.window?.addTabbedWindow(newWindow, ordered: .above)

        newWindow.orderFront(self.window)
        newWindow.makeKey()

        // Store the windowController in a collection of sorts
        // to keep a strong reference and make it handle events:
        // (NSApp.delegate as? AppDelegate).addManagedWindowController(windowController)
    }
}

newWindowForTab AppDelegate, , !

+4

, , "+" , , .

override func newWindowForTab(_ sender: Any?) {
    let wc: NSWindowController = self.storyboard?.instantiateInitialController() as! NSWindowController
    wc.window?.windowController = self
    NSApplication.shared.mainWindow!.addTabbedWindow(wc.window!, ordered: .above)
    wc.window?.orderFront(self)
}

NSApplication.shared.mainWindow! .

,

let tabbedWindows = NSApplication.shared.mainWindow!.tabbedWindows!
let lastTabIdx = tabbedWindows.count - 1
tabbedWindows[lastTabIdx].addTabbedWindow(wc.window!, ordered: .above)
0

Source: https://habr.com/ru/post/1658607/


All Articles