5

I'm migrating my iOS app to support MacCatalyst but I'd like to prevent the window from being resized by the user.

Do you have any tips for that?

DrMickeyLauer
  • 4,455
  • 3
  • 31
  • 67
marcelosalloum
  • 3,481
  • 4
  • 39
  • 63
  • 1
    I am also face same issue. Did you found any solution? – Hardik Thakkar Aug 07 '19 at 11:42
  • No, I haven't @HardikThakkar. It is possible to limit the size for MacOS apps, but apparently not (yet) for iOS apps that were built for mac – marcelosalloum Aug 07 '19 at 12:45
  • 1
    I answered a similar question here: https://stackoverflow.com/questions/57388389/xcode-11-disable-resize-mode-in-catalyst-swift/57398562#57398562 – Adam Aug 07 '19 at 16:21
  • 1
    This is so weird because I have the opposite problem. The app can't be resized and I want to to be resizable. – Victor Engel Nov 24 '21 at 01:47

5 Answers5

11

Since Xcode11 Beta 5, the UIWindowScene class started supporting the property sizeRestrictions.

If you set sizeRestrictions.maximumSize and sizeRestrictions.minimumSize to the same value, the window will not be resizable. To do so, just call this in your application:didFinishLaunchingWithOptions method (if you're using UIKit):

    UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.forEach { windowScene in
        windowScene.sizeRestrictions?.minimumSize = CGSize(width: 480, height: 640)
        windowScene.sizeRestrictions?.maximumSize = CGSize(width: 480, height: 640)
        windowScene.sizeRestrictions?.allowsFullScreen = false // optional
    }

If you're using SwiftUI instead of UIKit, you should actually add it to scene(_:willConnectTo:options:) in your scene delegate.

Note: You need to run this in OSX 10.15 Beta 5 or later, otherwise it will crash

marcelosalloum
  • 3,481
  • 4
  • 39
  • 63
4

In a SwiftUI App lifecycle this worked for me:

import SwiftUI

@main
struct MyApp: App {

  @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
  
  var userSettings = UserSettings()
  
  var body: some Scene {
    WindowGroup {
      ContentView()
        .environmentObject(userSettings)
        .environmentObject(KeyboardManager())
        .onOpenURL(perform: { url in
          let verificationCode = url.lastPathComponent
          log.info(" Verification Code: \(verificationCode)")
          userSettings.verificationCode = verificationCode
        })
      .onReceive(NotificationCenter.default.publisher(for: UIScene.willConnectNotification)) { _ in
        #if targetEnvironment(macCatalyst)
        // prevent window in macOS from being resized down
          UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.forEach { windowScene in
            windowScene.sizeRestrictions?.minimumSize = CGSize(width: 800, height: 1000)
          }
        #endif
      }
    }
  }
}
Steve
  • 89
  • 2
  • 6
  • Thank you! The .onReceive here worked very well for me too! I swapped it out with .task, though, and set .maximumSize to be equal minimumSize. Now I have the window the size I want :-) – niklassaers Jul 05 '21 at 17:49
0

In the file, SceneDelegate.swift, add this:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.forEach { windowScene in
        windowScene.sizeRestrictions?.minimumSize = CGSize(width: 1268, height: 880)
        windowScene.sizeRestrictions?.maximumSize = windowScene.sizeRestrictions!.minimumSize
    }
    
    guard let _ = (scene as? UIWindowScene) else { return }
}
0

for Objective-C try

for (UIScene* scene in UIApplication.sharedApplication.connectedScenes) {
    if ([scene isKindOfClass:[UIWindowScene class]]) {
        UIWindowScene* windowScene = (UIWindowScene*) scene;
        windowScene.sizeRestrictions.minimumSize = CGSizeMake(480, 640);
    }
}
0

Steve gave me the answer. Also add disable fullscreen

WindowGroup {
    ContentView()
    .onReceive(NotificationCenter.default.publisher(for: UIScene.willConnectNotification)) { _ in
        #if targetEnvironment(macCatalyst)
        // prevent window in macOS from being resized down
        UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.forEach { windowScene in
            windowScene.sizeRestrictions?.minimumSize = CGSize(width: 800, height: 1000)
            windowScene.sizeRestrictions?.maximumSize = CGSize(width: 800, height: 1000)
            windowScene.sizeRestrictions?.allowsFullScreen = false
        }
        #endif
    }
}
Salvador
  • 61
  • 1
  • 8