【问题标题】:Is it possible to use full screen in Mac Catalyst?是否可以在 Mac Catalyst 中使用全屏?
【发布时间】:2020-02-19 21:38:03
【问题描述】:

将游戏移植到 macOS Catalyst,但窗口很小。是否可以改为全屏启动?

【问题讨论】:

    标签: ios fullscreen uiwindow mac-catalyst


    【解决方案1】:

    没有简单的设置说“开始全屏”。但是您可以在启动时设置窗口的框架。

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
    
        #if targetEnvironment(macCatalyst)
        window?.frame = CGRect(origin: .zero, size: CGSize(width: 1600, height: 1000))
        #endif
    

    显然这并不理想,因为您不想硬编码特定的大小。

    你可以得到屏幕的大小如下。但在我自己的测试中,返回的值并不准确。这可能是 Mac Catalyst 中的一个错误。

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let winScene = (scene as? UIWindowScene) else { return }
    
        #if targetEnvironment(macCatalyst)
        let screen = winScene.screen
        let size = screen.nativeBounds.size
        window?.frame = CGRect(origin: .zero, size: size)
        #endif
    }
    

    这使它变大了,但并不是真正的全屏,因为至少在我的测试中,返回的屏幕尺寸实际上与屏幕尺寸不匹配。

    但这应该会给你一些想法。

    您还可以在屏幕上设置最小和最大尺寸:

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let winScene = (scene as? UIWindowScene) else { return }
    
        #if targetEnvironment(macCatalyst)
        if let sizes = winScene.sizeRestrictions {
            let screen = winScene.screen
            let size = screen.nativeBounds.size
            sizes.minimumSize = size
            sizes.maximumSize = size
        }
        #endif
    }
    

    在此示例中,屏幕不会调整大小,因为最小值和最大值相同。调整以适应您的应用程序的需求。如果您为 min 和 max 提供不同的值,如果您希望初始大小介于 min 和 max 设置之间,也可以将其与设置窗口框架结合使用。


    这是 Objective-C 中的相同解决方案:

    - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
        if (![scene isKindOfClass:[UIWindowScene class]]) { return; }
    
        UIWindowScene *winScene = (UIWindowScene *)scene;
    
    #if TARGET_OS_MACCATALYST
        UISceneSizeRestrictions *sizes = winScene.sizeRestrictions;
        if (sizes) {
            UIScreen *screen = winScene.screen;
            CGSize size = screen.nativeBounds.size;
            sizes.minimumSize = size;
            sizes.maximumSize = size;
        }
    #endif
    

    【讨论】:

    • 在 Catalina 中,屏幕尺寸始终报告为 1920x1080。现在应该将真实的屏幕尺寸报告给 Big Sur 中的 Catalyst 应用程序。参考。 developer.apple.com/forums/thread/…
    【解决方案2】:

    是的可以全屏启动。

    方法 #1(在 Mac Catalyst 应用中使用 AppKit 的更通用方式)

    要切换到全屏,您需要使用 AppKit 和 NSApplication 类,但目前这在 Mac Catalyst 应用程序中不可用。但是,您可以从另一个插件包访问它。这就是你如何做到这一点并在应用启动时切换到全屏:

    第 1 步。 您需要在您的应用中创建一个新的 mac 捆绑目标。单击文件 -> 新建 -> 目标 -> macOS -> 捆绑包,然后单击下一步按钮。输入产品名称,例如 MacBundle,然后单击完成按钮。

    第 2 步。 在您的项目中选择新创建的组 MacBundle,然后单击 File -> New -> macOS -> Cocoa Class,然后单击按钮 Next。输入类名,例如 MacApp,它是 NSObject 的子类,并将语言设置为 Objective-C。单击下一步,确保选择了 MacBundle 目标,然后单击按钮创建。

    第 3 步。 像这样编辑 MacApp.h:

    #import <Foundation/Foundation.h>
    #import <AppKit/AppKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface MacApp : NSObject
    
    + (void)toggleFullScreen;
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    第 4 步。 像这样编辑 MacApp.m:

    #import "MacApp.h"
    
    @implementation MacApp
    
    + (void)toggleFullScreen {
        [[[[NSApplication sharedApplication] windows] firstObject] toggleFullScreen:nil];
    }
    
    @end
    

    第 5 步。点击您的项目并在 Targets 部分中选择您的主应用目标(与 iOS 相同)

    第 6 步。 在“常规”选项卡中,向下滚动到“框架”、“库”和“嵌入内容”部分,然后单击 + 按钮。在选择框架的新弹出窗口中,选择 MacBundle.bundle 并单击按钮添加以将此包嵌入到您的主应用程序中。

    第 7 步。 现在您可以从主 iOS 代码的 MacBundle 中的 MacApp 类调用 toggleFullScreen 方法。为了让它工作,你可以从你的应用程序中出现的第一个 UIViewController 中的 viewDidAppear 调用一次。你可以这样称呼它:

    static var needsFullScreen = true
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if Self.needsFullScreen {
            Bundle(path: Bundle.main.builtInPlugInsPath?.appending("/MacBundle.bundle") ?? "")?.load()
            let macApp = NSClassFromString("MacApp") as? NSObjectProtocol
            macApp?.perform(NSSelectorFromString("toggleFullScreen"))
            Self.needsFullScreen = false
        }
    }
    

    或者,您可以使用该 toggleFullScreen 方法创建一个协议。

    之后,当您启动应用程序时,它会自动切换到全屏。

    方法 #2(对于这种特定情况,不太通用,但速度更快)

    如果你不打算使用其他 AppKit 的东西,那么对于前面方法中显示的这个 toggleFullScreen 调用,你可以在没有插件包的情况下从你的应用程序中出现的第一个 UIViewController 中的 viewDidAppear 调用它一次,如下所示:

    static var needsFullScreen = true
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if Self.needsFullScreen {
            (NSClassFromString("NSApplication")?.value(forKeyPath: "sharedApplication.windows") as? [AnyObject])?.first?.perform(Selector("toggleFullScreen:"))
            Self.needsFullScreen = false
        }
    }
    

    【讨论】:

    • 如果你打算在催化剂应用程序中使用运行时函数来访问MacApp,为什么要使用框架呢?你可以在没有框架的情况下调用toggleFullScreen:
    • 是的,你也可以这样做。如果您只想调用一个方法,这不会那么难,但如果您还需要在 NSApplication 上执行更复杂的东西,那将是非常痛苦的。所以上面的解决方案展示了一个更通用的解决方案,如果你需要访问其他 NSApplication 东西,以后更容易扩展。
    • 您可以在一行中使用DynamicDynamic.NSApplication.sharedApplication.windows.firstObject.toggleFullScreen(nil)
    【解决方案3】:

    您可以使用Dynamic 一行来完成:

    Dynamic.NSApplication.sharedApplication.windows.firstObject.toggleFullScreen(nil)
    

    【讨论】:

      【解决方案4】:

      要消除第 7 步中的警告:

          Bundle(path: Bundle.main.builtInPlugInsPath?.appending("/MacBundle.bundle") ?? "")?.load()
              
          let macClass: AnyClass? = NSClassFromString("MacApp")
              
          let macApp = macClass as AnyObject as? NSObjectProtocol
              
          macApp?.perform(NSSelectorFromString("toggleFullScreen"))
      

      【讨论】:

      • 你能帮忙用 Objective C 写这个吗?
      猜你喜欢
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多