iOS app on MacOS M1 - Window Resize or Full Screen

MacOS M1 machines can run iOS applications.

We have an iOS application that runs a fullscreen metal game. The game can also run across all desktop platforms via Steam. In additional to Steam, we would like to make it available through the AppStore on MacOS. We'd like to utilise our iOS builds for this so that the Apple payment (micro-transactions) and sign-in processes can be reused.

While the app runs on MacOS, it runs in a small iPad shaped window that cannot be resized. We do not want to add iPad multitasking support (portrait orientation is not viable), but would like the window on MacOS to be expandable to full screen. Currently there is an option to make it full screen, but the metal view (MTKView) delegate does not receive a drawableSizeWillChange event for this, meaning the new resolution of the window cannot be received.

Is there another method of retrieving a window size change event in this context? What is the recommended way of enabling window resizing on MacOS but not iPad for a single iOS app?

Accepted Reply

You are not being notified of a size change because there is no size change!

On Macs with M1, iPad apps that do not support iPad multitasking (as well as all iPhone apps) receive a single screen + scene size, which never changes after launch. This is done for compatibility reasons, because iPads and iPhones don't change their physical screen resolution on you, either.

When the window is resized, e.g. by using the Window->Zoom menu item, or by taking the window full screen, your fixed-size UIWindowScene is scaled up or down by macOS automatically, and your app does not find out about this.

And as you point out, iPad multitasking support would cause your window(s) to become resizable, but live-resizing of e.g. game framebuffers is often not feasible.

But I have good news for you!

We've added two new Mac-only Info.plist keys that may provide just what you need:

  • UISupportsTrueScreenSizeOnMac will give you the true native resolution of the screen where your app was initially launched. This implies that you are prepared to deal with the wide variety of display configurations that you might encounter on a Mac, including 1x and 2x display resolutions, ultrawide and portrait displays, as well as very small or very large sizes. For example, if your content needs to use a specific aspect ratio, it would be up to you to add letterboxing or pillarboxing, as needed.

  • UILaunchToFullScreenByDefaultOnMac will tell the system that your app prefers to enter fullscreen mode as soon as it's launched. However, note that state restoration will override this default behavior.

When you combine both keys, this gives your iPad app a pixel-perfect, edge-to-edge, full screen experience on Macs with M1!

Older versions of macOS (before 12.1) will simply ignore these keys, so you get standard iPad resolutions instead. And they are also ignored on all other platforms.

For more details, you can also check out the WWDC 2022 session, titled "Bring your iOS app to the Mac".

  • Thank you for your very informative post. The WWDC 2022 session was extremely useful. The 2 new keys are great for getting a native window size, however, on my Mac Mini I'm having an issue receiving the correct resolution with the MTKViewDelegate. At first, the drawableSizeWillChange() method is called with the width and height of my monitor reversed (height x width), then instantly called again with a resolution (huge width, small height) that does not match the window at all.

  • Thanks for this valuable information. The two new keys work perfectly. The only issue I had was not being notified of the correct drawable size, but I've worked around that by checking for window size changes periodically and specifying the drawable size to the window size multiplied by the native display scale factor.

  • One additional note: These keys only apply to apps with iPad support. For iPhone-only apps, a compatible iPhone size is chosen, and the app will not be taken to fullscreen mode by default.

Replies

You are not being notified of a size change because there is no size change!

On Macs with M1, iPad apps that do not support iPad multitasking (as well as all iPhone apps) receive a single screen + scene size, which never changes after launch. This is done for compatibility reasons, because iPads and iPhones don't change their physical screen resolution on you, either.

When the window is resized, e.g. by using the Window->Zoom menu item, or by taking the window full screen, your fixed-size UIWindowScene is scaled up or down by macOS automatically, and your app does not find out about this.

And as you point out, iPad multitasking support would cause your window(s) to become resizable, but live-resizing of e.g. game framebuffers is often not feasible.

But I have good news for you!

We've added two new Mac-only Info.plist keys that may provide just what you need:

  • UISupportsTrueScreenSizeOnMac will give you the true native resolution of the screen where your app was initially launched. This implies that you are prepared to deal with the wide variety of display configurations that you might encounter on a Mac, including 1x and 2x display resolutions, ultrawide and portrait displays, as well as very small or very large sizes. For example, if your content needs to use a specific aspect ratio, it would be up to you to add letterboxing or pillarboxing, as needed.

  • UILaunchToFullScreenByDefaultOnMac will tell the system that your app prefers to enter fullscreen mode as soon as it's launched. However, note that state restoration will override this default behavior.

When you combine both keys, this gives your iPad app a pixel-perfect, edge-to-edge, full screen experience on Macs with M1!

Older versions of macOS (before 12.1) will simply ignore these keys, so you get standard iPad resolutions instead. And they are also ignored on all other platforms.

For more details, you can also check out the WWDC 2022 session, titled "Bring your iOS app to the Mac".

  • Thank you for your very informative post. The WWDC 2022 session was extremely useful. The 2 new keys are great for getting a native window size, however, on my Mac Mini I'm having an issue receiving the correct resolution with the MTKViewDelegate. At first, the drawableSizeWillChange() method is called with the width and height of my monitor reversed (height x width), then instantly called again with a resolution (huge width, small height) that does not match the window at all.

  • Thanks for this valuable information. The two new keys work perfectly. The only issue I had was not being notified of the correct drawable size, but I've worked around that by checking for window size changes periodically and specifying the drawable size to the window size multiplied by the native display scale factor.

  • One additional note: These keys only apply to apps with iPad support. For iPhone-only apps, a compatible iPhone size is chosen, and the app will not be taken to fullscreen mode by default.

So can we get a resizable window with iOS on macOS? I'm confused by this statement. Currently we require fullscreen, and only support landscape. But if I turn off UIRequiresFullscreen and state we support all orients, I can get a resizable window. Some elements scale, and other do not. Does that mean that I need to respond to the UIWindowScene scaling, or is the main render always fullscreen size?

"When the window is resized, e.g. by using the Window->Zoom menu item, or by taking the window full screen, your fixed-size UIWindowScene is scaled up or down by macOS automatically, and your app does not find out about this."

  • Yes, you can get resizable windows for your iPad app on macOS, by adding support for resizable scenes (see this thread for details). But this means that the layout of your UI has to be able to handle scene size changes.

    UIRequiresFullscreen explicitly opts you out of resizable scenes / windows, and the pixels of those fixed-size UIWindowScenes get scaled up or down on the Mac, without your app knowing about it.

Add a Comment

None of the threads mentioned above help. We just need sample code that shows an iOS on macOS app resizing. There is none. Even the sample showing the UISupportsTrueScreenSizeOnMac and UILaunchToFullScreenByDefaultOnMac keys is set to UIRequiresFullscreen. Turning that off and making sure the orients are all specified allows the window to resize, but the MTKView in a game needs to respond to that. UIWindowScene requires iOS 13, isFullscreen flag requires iOS 16, isiOSAppOnMac requires iOS 14. So this is a minefield of trying to get everything right. This needs a sample app, and not references to pages that don't have details.

Having an iOS app switch from fullscreen to windowed and maintain the same resolution regardless of the window size is not a good experience. The UI becomes distorted and the size too small. Dragging from landscape monitor to portrait monitors results in letterboxing instead of filling the display. This needs to be the default behavior for iOS on macOS apps.