mike
mike

Reputation: 639

How to hide the top bar (with buttons) usin Swift and MacOS?

I'm trying to remove the title and top buttons from the window and basically display only the content. I've tried various things with no success without any apparent reason why it's not working. See setVisibility function for the options I've tried

AppDelagate.swift

 import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    @IBOutlet weak var window: NSWindow!

    func setVisibility(){
        self.window?.titlebarAppearsTransparent = true;
        self.window?.styleMask = .borderless
        self.window?.titleVisibility = .hidden
        self.window?.styleMask.insert(.fullSizeContentView)
        /*
         self.window?.standardWindowButton(.zoomButton)!.isHidden = true
         self.window?.standardWindowButton(.closeButton)!.isHidden = true
         */
        self.window?.level = .floating
        self.window?.center()
        self.window?.collectionBehavior = .canJoinAllSpaces
        //self.window?.collectionBehavior = .moveToActiveSpace
    }

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        setVisibility()
        NSApp.activate(ignoringOtherApps: true)

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

    func applicationDidBecomeActive(_ aNotification: Notification) {
       setVisibility()
        NSApp.activate(ignoringOtherApps: true)

    }


    func applicationWillResignActive(_ aNotification: Notification) {
        setVisibility()
        NSApp.activate(ignoringOtherApps: true)

    }


    func applicationWillEnterForeground(_ aNotification: Notification) {
        setVisibility()
        NSApp.activate(ignoringOtherApps: true)

    }

    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        NSApp.terminate(self)
        return true
    }
}

ViewController.swift I'm just embedding a webkit view. Nothing fancy.

import Cocoa
import WebKit
import os

class ViewController: NSViewController, WKUIDelegate, WKNavigationDelegate {
    @IBOutlet weak var window: NSWindow!



    let webView = WKWebView()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.uiDelegate = self
        self.webView.navigationDelegate = self
        webView.frame = CGRect(x: 0, y: 0, width: 1200, height: 600)
         view.addSubview(webView)
        let url = URL(string: "http://localhost:8080/?x=y")
        //let url = URL(string: "https://apple.com")
        let request = URLRequest(url: url!)
        webView.load(request)

    }


    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void)
    {
            if navigationAction.request.url?.path == "/close" || navigationAction.request.url?.path == "/close/"{
                exit(0);
            }
        decisionHandler(.allow)
    }

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


}

Upvotes: 2

Views: 3629

Answers (1)

mxgzf
mxgzf

Reputation: 946

What you want is a window with a style mask of type NSWindowStyleMaskBorderless. The problem is that this has to be set when initializing the window. That's why your line self.window?.styleMask = .borderless has no effect.

Because you are creating your window using Interface Builder, you have to open the corresponding xib file (I guess MainMenu.xib), select the window and deselect Title Bar in the Attributes inspector:

Title Bar

I know. This is confusing. But at least Apple mentions it in the documentation:

Note that you can set a window’s or panel’s style mask to NSWindowStyleMaskBorderless in Interface Builder by deselecting Title Bar in the Appearance section of the Attributes inspector.

If you want to learn more about the different styles of a NSWindow checkout NSWindowStyles by Luka Kerr. That's a great reference.

Update: In said reference i found another way to remove the title bar that might work for you:

window?.styleMask.remove(.titled)

Upvotes: 3

Related Questions