Set window size based on mac screen size using catalyst supported APIs - swift

I am trying to get the application to be the size of the full screen using Catalyst supported APIs. I have tried using the UIScreen proeprty as well as the window property(below), but both have the problem where the window does not fill the full screen.
I have attached my code, but the window does not occupy the full screen size.
let windowRect = self.window?.frame
let windowWidth = windowRect?.size.width
let windowHeight = windowRect?.size.height
UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.forEach { windowScene in
windowScene.sizeRestrictions?.minimumSize = CGSize(width: windowWidth! , height:windowHeight! )
windowScene.sizeRestrictions?.maximumSize = CGSize(width: windowWidth!, height: windowHeight!)
}

Related

Xcode scene size GUI values ignored for macOS apps

The scene size values, set via the Xcode GUI, seem to only apply to iOS and are ignored by macOS.
So I programmatically set the window size of my macOS app, within NSViewController, using:
self.view.frame.size = NSSize(width: 375, height: 650)
or even something like:
let screenWidth = NSScreen.main?.frame.width
let screenHeight = NSScreen.main?.frame.height
let windowSize = NSSize(width: screenWidth!/4, height: screenHeight!/2)
self.view.frame.size = windowSize
Is this the correct way to set the window size or am I missing something?

Mac Catalyst - Make window NSToolbar transparent

Problem
Hi All,
I need help to make my window NSToolbar transparent, however, I still need to be able to use a toolbar within the window scene titlebar. Currently, you can set a titlebar to be transparent by either hiding your toolbar or not having one at all, but even though I will not be adding any actual tools within the toolbar, there needs to be one so that I can reposition the window traffic light buttons using the UITitlebarToolbarStyle property - I know that from Electron 8, developers are able to reposition the traffic light buttons (is this also possible in Swift?)
Any help is much appreciated 😊
Current Code
- this is situated within the AppDelegate
guard let windowScene = (scene as? UIWindowScene) else { return }
#if targetEnvironment(macCatalyst)
windowScene.sizeRestrictions?.minimumSize = CGSize(width: 1366 * 0.9, height: 1024 * 0.9)
if let titlebar = windowScene.titlebar {
let customToolbar = NSToolbar()
titlebar.titleVisibility = .hidden
titlebar.toolbar = customToolbar
titlebar.toolbarStyle = .unified
titlebar.autoHidesToolbarInFullScreen = true
}
#endif
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.makeKeyAndVisible()

How do I create and print an offscreen SwiftUI view on Mac not iPhone

For over a week I have been trying to solve a printing issue in a macOS app I am writing using Swift and SwiftUI.
I need to print a view, which I have done by making it the main window but that does not work for the user. The data can come from a file or directly from user input so could be from 1 to 100 data sets.
Because I am printing the main window the application is unusable during the print process which is not acceptable.
The ideal solution would be to create the view off-screen then print the view. That way the user never sees it other than what comes out of the printer!
I have tried to find out how to print a view that is not the main window - no success, tried creating a second window managed to create the window but not print it!
No point in posting code as no idea which of the several ways I have tried could work, not even sure at this point if what I am trying to do is possible!
Please note this on Mac, not iPhone or iPad!
This worked for me, borrowed from the link in the comment from #Willeke. It involves converting to a bit map for printing.
let printInfo = NSPrintInfo()
let view = ContentView()
let contentRect = NSRect(x: 0, y: 0, width: 1080, height: 720) // these values will vary
let viewToPrint = NSHostingView(rootView: view)
viewToPrint.frame = contentRect
let bitMap = viewToPrint.bitmapImageRepForCachingDisplay(in: contentRect)!
viewToPrint.cacheDisplay(in: contentRect, to: bitMap)
let image = NSImage(size: bitMap.size)
image.addRepresentation(bitMap)
let imageView = NSImageView(frame: contentRect)
imageView.image = image
let printOperation = NSPrintOperation(view: imageView, printInfo: self.printInfo)
printOperation.showsPrintPanel = true
printOperation.showsProgressPanel = true
printOperation.run()

How to open a windowcontroller on top of a maximised windowcontroller

I have a osx (MacOS) application with a mainwindowController and the user can maximise the view. The app also has a preferences window that opens as a childwindowcontroller.
However if the main window is maximised the child window also tries to be maximised which ends up with a black screen with the child window display in the middle.
Is there anyway to make the child window not be displayed based on the main window maximised state and the child window always not be maximised.
Here is some code of how the preferences window is displayed.
let currentWindowController = self.view.window?.windowController as! MainWindowViewController
let childWindowControllers = windowControllers[currentWindowController]
if let subPreferencesWindowController: SubPreferenceWindowViewController? = {
for windowController in childWindowControllers! {
if windowController is SubPreferenceWindowViewController {
return windowController as? SubPreferenceWindowViewController
}
}
return nil
}(){
let subPreferencesController = subPreferencesWindowController?.contentViewController as! SubPreferenceViewController
subPreferencesController.appStateJSON = self.appStateJSON!
subPreferencesController.preferences = self.preferencesJSON!
subPreferencesController.setUpSubPreferences()
}
SOLVED IT - When I create the window I add a styling mask to set the new window to not be resizable. (Last line of code)
if let subPreferenceViewController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "sub-preferences")) as? SubPreferenceViewController {
let subPreferenceWindow = NSWindow(contentViewController: subPreferenceViewController)
let subPreferenceWindowController = SubPreferenceWindowViewController(window: subPreferenceWindow)
var windowControllersForCurrent = windowControllers[currentWindowController]
windowControllersForCurrent?.append(subPreferenceWindowController)
windowControllers[currentWindowController] = windowControllersForCurrent
newWindowController = subPreferenceWindowController
newWindow = subPreferenceWindow
newWindow.standardWindowButton(.zoomButton)!.isHidden = true
width = 400
height = 607
newWindow.maxSize = NSSize(width: width, height: height)
newWindow.styleMask.remove(.resizable)
}

Window animates width but not height

I have a preferences window with a NSTabViewController hooked up to the toolbar for selecting tabs. I want the window to be resizable, and to resize if necessary when switching tabs to fit the new tab's size.
I'm subclassing NSTabViewController with the following overload:
override var selectedTabViewItemIndex: Int
{
didSet
{
guard let view = tabViewItems[selectedTabViewItemIndex].view,
let window = view.window
else { return }
let minSize = view.fittingSize
let contentRect = NSWindow.contentRect(forFrameRect: window.frame,
styleMask: window.styleMask)
let minRect = NSRect(origin: contentRect.origin, size: minSize)
let newRect = minRect.union(contentRect)
let newFrame = NSWindow.frameRect(forContentRect: newRect,
styleMask: window.styleMask)
window.animator().setFrame(newFrame, display: true, animate: true)
}
}
The result is that it animates resizing horizontally, and at the end it suddenly resizes vertically as well. How do I get it to just animate both directions at once?
Do you have height constraints on any of the tabs? Those might prevent the window from getting larger (even while offscreen).