user14243629
user14243629

Reputation: 31

NSPopover in Mac Catalyst for Mac menu bar

I am trying to add a MenuBar Item to my Mac Catalyst app.

I have successfully made the iPad app work on Mac, but adding the MenuBar item is turning out to be quite difficult.

I have tried solving the issue using the following two links, but they don't have a GitHub repo which I can look at, and the explanations do some jumps.

https://www.highcaffeinecontent.com/blog/20190607-Beyond-the-Checkbox-with-Catalyst-and-AppKit https://developer.apple.com/documentation/xcode/creating_a_mac_version_of_your_ipad_app

Right now I have the following code in my AppDelegate:

#if targetEnvironment(macCatalyst)
    import AppKit
    import Cocoa

#endif
import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    #if targetEnvironment(macCatalyst)
        var popover: NSPopover!
        var statusBarItem: NSStatusItem!
    #endif

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        #if targetEnvironment(macCatalyst)
        // Code to include from Mac.
        #endif
        #if targetEnvironment(macCatalyst)
            let contentView = MenuBarView()

            // Create the popover
            let popover = NSPopover()
            popover.contentSize = NSSize(width: 400, height: 500)
            popover.behavior = .transient
            popover.contentViewController = NSHostingController(rootView: contentView)
            self.popover = popover
            
            // Create the status item
            self.statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(NSStatusItem.variableLength))
            
            if let button = self.statusBarItem.button {
                button.image = NSImage(named: "MenuBar")
                button.action = #selector(togglePopover(_:))
            }
        #endif
        
        return true
    }
    
    #if targetEnvironment(macCatalyst)
        @objc func togglePopover(_ sender: AnyObject?) {
             if let button = self.statusBarItem.button {
                  if self.popover.isShown {
                       self.popover.performClose(sender)
                  } else {
                       self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
                        self.popover.contentViewController?.view.window?.becomeKey()
                  }
             }
        }
    #endif
    
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let windowScene = (scene as? UIWindowScene) else { return }
        
        #if targetEnvironment(macCatalyst)
        if let titlebar = windowScene.titlebar {
            titlebar.titleVisibility = .hidden
            titlebar.toolbar = nil
        }
        #endif

    }

...more code from CoreData

The Errors that is is showing The Errors that is is showing

I am really new to iOS development and I am getting really lost, so any and every help is really appreciated.

Edit

Yes, the screenshot is from the AppDelegate.

I am trying to implement something like this: https://github.com/AnaghSharma/Ambar-SwiftUI

every implementation that I have seen thus far put this into the AppDelegate, which is why I am trying to do the same thing as well.

Upvotes: 2

Views: 2025

Answers (2)

cuttlas
cuttlas

Reputation: 981

If I'm not mistaken, it's not possible to use NSPopover in Mac Catalyst yet. From apple documentation:

Mac apps built with Mac Catalyst can only use AppKit APIs marked as available in Mac Catalyst, such as NSToolbar and NSTouchBar. Mac Catalyst does not support accessing unavailable AppKit APIs.

And Mac Catalyst is not listed in the availability platforms list:

https://developer.apple.com/documentation/appkit/nspopover

Upvotes: 1

Adam
Adam

Reputation: 5145

From your screenshot, it looks like that’s the AppDelegate for your Mac bundle. If that’s the case, then you need to remove all the UIKit and #if TARGET_MAC_CATALYAT stuff and do everything in AppKit. That is, use NSResponder instead of UIResponder, etc.

As for sample code, this is a great start: https://github.com/noahsark769/CatalystPlayground

It includes an AppKit bundle and the code for loading it.

Upvotes: 2

Related Questions