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

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

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:
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)

Related

WKWebView won't display the webpage I need it to

Given the code below. I can't get the web page "https://baycare.clearstep.health/covid19" to show up. It shows up okay in Safari and I can get other pages to show up in the WKWebView. I have tried implementing all of the navigation and ui delegate methods to try and track down the problem but have failed to find anything.
The URL used to work, but the company has changed something and now it doesn't. Any help is appreciated.
The below is a complete program:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller = UIViewController()
.setup { viewController in
WKWebView(frame: viewController.view.bounds)
.setup {
viewController.view.addSubview($0)
$0.uiDelegate = WebViewUIDelegate.instance
$0.navigationDelegate = WebViewDelegate.instance
$0.autoresizingMask = [.flexibleWidth, .flexibleHeight]
$0.load(URLRequest(url: URL(string: "https://baycare.clearstep.health/covid19")!))
}
}
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = controller
window?.makeKeyAndVisible()
return true
}
}
extension NSObjectProtocol {
#discardableResult
func setup(_ fn: (Self) -> Void) -> Self {
fn(self)
return self
}
}
final class WebViewUIDelegate: NSObject, WKUIDelegate {
static let instance = WebViewUIDelegate()
}
final class WebViewDelegate: NSObject, WKNavigationDelegate {
static let instance = WebViewDelegate()
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print("This doesn't fire so no error?", error)
}
}
WKWebView is depricated version but still webview will works fine, I had same issue and I was doing same but then instead of WKWenView I used web view
import UIKit
import WebKit
class PolicyVC: UIViewController {
#IBOutlet weak var webView: UIWebView!
var isPolicyView = false
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: UIButton.ButtonType.custom)
button.setImage(UIImage(named: "ic_arrow_left"), for: .normal)
button.addTarget(self, action:#selector(popView), for: .touchUpInside)
button.frame=CGRect(x: 0, y: 0, width: 20, height: 20)
let barButton = UIBarButtonItem(customView: button)
self.navigationItem.leftBarButtonItems = [barButton]
setUpUI()
}
#objc func popView(){
self.navigationController?.popViewController(animated: true)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.backgroundColor = .black
}
func setUpUI(){
if isPolicyView{
let url = URL(string: "https://www.termsfeed.com/privacy-policy/68c4cdaeba7e146a7d72bf57654520e7")
let urlRequest = URLRequest(url: url!)
webView.loadRequest(urlRequest)
}else{
let url = URL(string: "https://www.termsfeed.com/terms-conditions/0001db2c7a1061a55e2f933bb94102de")
let urlRequest = URLRequest(url: url!)
webView.loadRequest(urlRequest)
}
}
}

Checking for key down on menu bar application

I am writing a MacOS Menu Bar Application which uses a popover. I have relied on a number of tutorials to get things going.
Very briefly, the code looks something like this:
class AppDelegate: NSObject, NSApplicationDelegate {
var popover=NSPopover()
var statusBarItem: NSStatusItem!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Popover & Content View
let contentView = ContentView()
self.popover.contentViewController = NSHostingController(rootView: contentView)
// Menu
self.statusBarItem = NSStatusBar.system.statusItem(withLength: 18)
if let statusBarButton = self.statusBarItem.button {
statusBarButton.title = "☰"
statusBarButton.action = #selector(togglePopover(_:))
}
}
#objc func togglePopover(_ sender: AnyObject?) {
let statusBarButton=self.statusBarItem.button!
func show(_ sender: AnyObject) {
self.popover.show(relativeTo: statusBarButton.bounds, of: statusBarButton, preferredEdge: NSRectEdge.maxY)
}
func hide(_ sender: AnyObject) {
popover.performClose(sender)
}
self.popover.isShown ? hide(sender as AnyObject) : show(sender as AnyObject)
}
}
How can I check whether the option key is down when the menu button is clicked?
Ask the current event whether the modifier flags contain option
func isOptionkeyPressed() -> Bool
{
return NSApp.currentEvent?.modifierFlags.contains(.option) == true
}

Why is windowDidMove() not being called? [duplicate]

I'm trying to know when a window closes, I implemented this code:
class ViewController: NSViewController, NSWindowDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let window: NSWindow? = view.window
window?.delegate = self
}
func windowWillClose(_ aNotification: Notification) {
print("windowWillClose")
}
}
Unfortunately nothing happens, what could I made wrong?
Documents: https://developer.apple.com/documentation/appkit/nswindow/1419400-willclosenotification
PS
I already read this question without to find a solution: Handle close event of the window in Swift
The problem there is that the window property will always return nil inside viewDidLoadMethod. You need to set the delegate inside viewWillAppear method:
class ViewController: NSViewController, NSWindowDelegate {
override func viewWillAppear() {
super.viewWillAppear()
view.window?.delegate = self
}
func windowWillClose(_ aNotification: Notification) {
print("windowWillClose")
}
}

Trying to know when a window closes in a macOS Document based application

I'm trying to know when a window closes, I implemented this code:
class ViewController: NSViewController, NSWindowDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let window: NSWindow? = view.window
window?.delegate = self
}
func windowWillClose(_ aNotification: Notification) {
print("windowWillClose")
}
}
Unfortunately nothing happens, what could I made wrong?
Documents: https://developer.apple.com/documentation/appkit/nswindow/1419400-willclosenotification
PS
I already read this question without to find a solution: Handle close event of the window in Swift
The problem there is that the window property will always return nil inside viewDidLoadMethod. You need to set the delegate inside viewWillAppear method:
class ViewController: NSViewController, NSWindowDelegate {
override func viewWillAppear() {
super.viewWillAppear()
view.window?.delegate = self
}
func windowWillClose(_ aNotification: Notification) {
print("windowWillClose")
}
}

MacOS statusbar app show menu and run function on click with swift 3

I'm making a small menubar app with Swift 3, I want the app to reload some data when I click the icon, but I also want it to show the statusMenu?
Below is a sample of my code:
// AppDelegate.swift
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var statusMenu: NSMenu!
#IBAction func quitClicked(_ sender: NSMenuItem) {
NSApplication.shared().terminate(self)
}
let statusItem = NSStatusBar.system().statusItem(withLength: NSVariableStatusItemLength)
func applicationDidFinishLaunching(_ aNotification: Notification) {
if let button = statusItem.button {
button.title = "App"
button.action = #selector(AppDelegate.doSomething(sender:))
statusItem.menu = statusMenu
}
}
func applicationWillTerminate(_ aNotification: Notification) {
}
func doSomething(sender: AnyObject?) {
NSLog("do something")
}
}
if I comment out
// statusItem.menu = statusMenu
The doSomething() function will run, but I can't figure out how to both show the menu and run the doSomething function, how can I do that?
Set the delegate of the menu to the application delegate (or another object) and implement optional func menuWillOpen(_ menu: NSMenu) of the NSMenuDelegate protocol.