Mac Catalyst应用升级Xcode后根窗口出现标签页,如何移除标签功能?
Mac Catalyst应用升级Xcode后根窗口出现标签页,如何移除标签功能?
我太懂这种升级后突然冒出来意料之外功能的糟心感了!从Xcode 12.4(对应Mac Catalyst 13.6)升级到16.4(Mac Catalyst 15.x)后,系统默认开启了窗口标签页功能,这确实会打乱原有应用的交互逻辑。你尝试的代码方向是对的,但可能时机或者细节没踩准,我给你分享几个更稳妥的解决方法:
方法一:通过Info.plist全局禁用标签页(最省心)
直接在应用的Info.plist文件里添加配置,从根源上关掉标签页功能,不需要写一行代码:
- 找到你的Info.plist文件,右键选择"Open As" -> "Source Code"
- 添加以下键值对:
<key>NSWindowTabbingMode</key> <string>disallowed</string>
这个配置会全局禁止应用所有窗口的标签页功能,系统不会再自动给窗口加上标签栏。
方法二:代码层面精准控制(适合需要灵活设置的场景)
如果你的应用需要针对特定窗口控制,或者想用代码确保生效,推荐在场景初始化的时机设置,而不是依赖mainWindow或者通知(因为通知可能会有延迟或者漏触发的情况):
步骤1:在Scene Delegate中设置窗口标签模式
在scene(_:willConnectTo:options:)方法里,拿到窗口对应的NSWindow,直接设置tabbingMode:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } // 获取对应的NSWindow if let nsWindow = windowScene.titlebar?.window { nsWindow.tabbingMode = .disallowed // 确保标签栏已经隐藏(如果已经显示的话) if nsWindow.isTabBarVisible { nsWindow.toggleTabBar(nil) } } // 剩下的原有初始化代码 let window = UIWindow(windowScene: windowScene) self.window = window // ... }
步骤2:处理已存在的窗口(防止遗漏)
如果担心有些窗口是后续创建的,可以在sceneDidBecomeActive(_:)里再补一遍检查,确保所有窗口都生效:
func sceneDidBecomeActive(_ scene: UIScene) { // 遍历应用所有窗口,强制禁用标签页 for window in NSApplication.shared.windows { window.tabbingMode = .disallowed if window.isTabBarVisible { window.toggleTabBar(nil) } } }
你之前代码可能踩的坑
- 时机问题:如果在
application(_:didFinishLaunchingWithOptions:)里设置mainWindow,这时候mainWindow可能还没完全初始化,导致设置无效 - 遍历窗口的细节:你之前遍历
NSApplication.shared.windows的时候,要确保每个窗口都设置window.tabbingMode = .disallowed,并且检查isTabBarVisible来隐藏已显示的标签栏 - 场景架构适配:Mac Catalyst现在用的是UIKit的Scene架构,依赖
NSApplication的API有时候不如从UIWindowScene获取窗口更可靠
试试上面的方法,应该能彻底解决标签页冒出来的问题!如果还有特殊场景没覆盖到,可以再补充你的应用细节,我再帮你调整方案~




