在 iOS 上选择退出 UISceneDelegate/SwiftUI

Opt out of UISceneDelegate/SwiftUI on iOS

我目前正在使用 Xcode 11 Beta 5。在我的应用程序中,它在 iOS 12 及以下版本上运行良好。但是,在 iOS 13 上,它似乎默认使用 UIScene。这导致我的应用程序无法执行任何操作。

当应用以全新安装方式启动时,用户必须接受一项条款和条件。同意后,他们会进入加载屏幕,然后将他们引导至主视图。在我发布的屏幕截图中,前景中当前视图后面的视图是启动加载屏幕。

我们将很快考虑在整个应用程序中添加多视图场景支持,但现在我们有更高优先级的事情需要处理。

“支持多个 windows”已在应用目标的常规设置中禁用。另外,我在 info.plist 文件中将 Enable Multiple Windows 设置为 NO。

到目前为止,没有任何效果。基本上我想选择 out/disable 多个 windows 和 UIScene/SwiftUI 来恢复 iOS 10-12 中的原始行为。这在 iOS 13 中是否可行,或者我们必须更新它?

更新:

这是视图调试层次结构的屏幕截图。左侧是 iOS 12,右侧是 iOS 13。没有向 Info.plist 添加任何内容,也没有添加任何场景委托 类 或方法,为什么会有所不同?几乎只是 运行 它在 Xcode 11.

上现有的生产就绪代码中

这也是我遇到的问题,这里有几种情况:

  • 如果您想在 Xcode 11 中使用 现有的 UIKit 应用程序,只需将其打开即可正常运行。我所有的应用程序都有 没有 SceneDelegate 文件,也没有对 AppDelegate 或情节提要进行任何更改。
  • 如果您想创建一个 新的 UIKIT 应用程序,目标 iOS 13,只需创建它,同时确保保留“使用 SwiftUI”复选框未选中。

但我想知道您是否面临第三种情况 - 我大约一周前遇到过这种情况。创建一个 新的 `UIKit 应用程序,目标早于 iOS 13。 (我居然瞄准了iOS9!)

是的,您的模板会给您 15 个错误(从 beta 5 开始),以及 SceneDelegate file/class。幸运的是,Xcode 将帮助您自动更正除一个以外的所有内容。

最后一个是添加一行,它是 SceneDelegate class 的一部分,但不幸的是 Apple 将其排除在 AppDelegate class 之外 - 在更多之后超过一打 @available(iOS 13.0, *) 条款意味着你选择退出 SceneDelegate if 运行 iOS 12 你猜怎么着? ApDelegate

将此添加到您的 AppDelegate:

var window: UIWindow?

到那时,您应该有一个针对 iOS 12 及更早版本的 运行 UIKit 应用程序。

当您的应用 运行 低于 iOS 13 及更高版本时,您 应该 拥抱使用场景,但您可以完全选择退出,同时您仍然支持 iOS 12 或更早。

  • 从Info.plist中完全删除“Application Scene Manifest”条目。

  • 如果有场景代理class,删除它。

  • 如果您的应用委托中有任何与场景相关的方法,请删除这些方法。

  • 如果缺少,请将 属性 var window: UIWindow? 添加到您的应用委托中。

您的应用现在应该只使用应用委托,并且在 iOS 13 下它应该具有与 iOS 12 相同的生命周期。

注意:None这个是特定于Swift或SwiftUI.

好的,我明白了。由于 iOS 13 Apple 新的默认卡片展示样式的变化,在我的故事板中,从我的启动画面到我的自定义流导航控制器默认为新展示(见下面的屏幕截图)。

我如何解决这个问题是回到默认为旧生命周期的旧样式。请参阅下面的屏幕截图。

不确定为什么会这样,因为这是我的应用程序中唯一导致此问题的地方(相当大的应用程序,所以我必须花一些时间检查所有故事板才能确定)。

我使用 dfd 的答案让它工作,但因为我的应用程序在 Objective-C 中,所以我必须进行一项更改:

在Objective-C中,你想把

@property (strong, nonatomic) UIWindow *window;

在 AppDelegate.h 中(不在 .m 中)

Xcode 12 - Swift 5.3 - iOS 14

自 Xcode 12 起,在 Swift 5.3 和 @main 的帮助下,您可以拥有一个没有 SceneDelegate 或事件 [=13= 的多平台应用程序].只有一个简单的文件,如:

import SwiftUI

@main
struct MyMultiPlatformApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

虽然您希望选择退出,但有时阻止它找到您的 sceneDelegate 文件的问题在于 info.plist 文件。

如果您在 info.plist 中有这个。

Scene Configuration
    Application Session Role
        Item 0 (Default Configuration)
            Delegate Class Name : SceneDelegate
            Storyboard Name : Main

应该是。

Scene Configuration
    Application Session Role
        Item 0 (Default Configuration)
            Delegate Class Name : $(PRODUCT_MODULE_NAME).SceneDelegate
            Storyboard Name : Main