在 iOS 上选择退出 UISceneDelegate/SwiftUI

Posted

技术标签:

【中文标题】在 iOS 上选择退出 UISceneDelegate/SwiftUI【英文标题】:Opt out of UISceneDelegate/SwiftUI on iOS 【发布时间】:2019-08-12 19:15:30 【问题描述】:

我目前正在使用 Xcode 11 Beta 5。在我的应用程序中,它在 ios 12 及更低版本上运行良好。但是,在 iOS 13 上,它看起来默认使用 UIScene。这导致我的应用程序不执行任何操作。

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

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

“支持多个窗口”已在应用程序目标的常规设置中禁用。我还在 info.plist 文件中将 Enable Multiple Windows 设置为 NO。

到目前为止,还没有真正奏效。基本上我想选择退出/禁用多个窗口和 UIScene/SwiftUI 以恢复 iOS 10-12 中的原始行为。这在 iOS 13 中是否可行,或者我们必须更新它?

更新:

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

【问题讨论】:

您需要只支持iOS 13及更高版本还是需要同时支持iOS 13和iOS 12? @rmaddy 支持 iOS 11-13+(未来版本)。 你的主界面是通过代码还是故事板? @rmaddy 它是在故事板中完成的,它被引用的 xib ViewControllers 有一个segue。 如果没有关于您的应用正在做什么以及何时执行的具体细节,很难说清楚。请注意,例如 viewWill|DidAppear 等视图控制器方法在关闭呈现的视图控制器时在 iOS 13 中的调用方式不同。添加大量生命周期调试消息和断点,比较 iOS 12 和 13 之间的流程,看看有什么不同。 【参考方案1】:

虽然您应该在您的应用在 iOS 13 及更高版本下运行时支持使用场景,但您可以在仍支持 iOS 12 或更早版本时完全退出。

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

如果有场景委托类,删除它。

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

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

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

注意:这些都不是 Swift 或 SwiftUI 特有的。

【讨论】:

同样的事情发生在我身上,我的 Info.plist 中没有清单条目,也没有任何 AppDelegate 方法,也没有 SceneDelegate 类。我将我的控制器设置为 David 作为 rootViewController 的“条款和条件”,它看起来与上面问题中所示的相同。请帮忙,因为我遇到了这个 UI 故障并且无法继续前进.. ugh! @MohsinKhubaibAhmed 你问的是一个完全不同的问题。见***.com/questions/56435510/… 您好!我按照 3 步说明进行操作,但在启动屏幕出现后出现黑屏。主故事板被选中,也是初始视图控制器。你有什么建议吗? @user3191334 我也遇到了黑屏。在我的情况下,它是黑暗模式,给了我一个默认的黑色背景。将一些内容添加到您的基本情节提要中,所有内容都会出现。 感谢您的回答。在将rootViewController 设置为我的自定义视图控制器时,我也遇到了黑屏,忘记了在将window 属性添加到AppDelegate 之后我需要实际实例化它。不要忘记这样做! window = UIWindow(),如果你还没有这样做的话。【参考方案2】:

这也是我面临的问题,这里有几个场景在起作用:

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

但我想知道您是否面临第三种情况——我大约一周前所做的。创建一个针对早于 iOS 13 的新的 `UIKit 应用。 (我实际上是针对 iOS 9 的!)

是的,您的模板将提供 15 个错误(从 beta 5 开始),以及一个 SceneDelegate 文件/类。幸运的是,Xcode 将帮助您自动更正除一个之外的所有内容。

最后一个是添加一行,它是 SceneDelegate 类的一部分,但不幸的是,Apple 将其排除在 AppDelegate 类之外 - 在十几个 @available(iOS 13.0, *) 子句之后意味着您已选择退出SceneDelegate 如果运行 iOS 12,你猜怎么着?它ApDelegate

将此添加到您的 AppDelegate:

var window: UIWindow?

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

【讨论】:

谢谢。我的场景几乎就是你所说的第一点,Xcode 11 中现有的 UIKit 应用程序。但是当我打开它时,它不能正常工作。查看我添加的视图调试层次结构的更新。 AppDelegate中也已经有了var window: UIWindow? 你让我担心! (而且我仍然有点担心。)我对现有应用程序的更新很少 - 上周对 SwiftUI 感到沮丧,我很想在 UIKit 中尝试仅适用于 iOS 13 的布局。但我现有的应用程序?他们支持 iPad 多任务处理,但在 Xcode 11 中 保持不变 我没有 SceneDelegate 并且测试说 (a) 他们在 iOS 13 中工作并且 (b) 他们根本不支持多个窗口,只是在两个应用程序之间拆分视图。 (我也不支持拖放。)你那边还有其他事情吗? 重复一遍,我只是在 Xcode 11 中打开了我的 Xcode 10 应用程序。没有SceneDelegate,没有SwiftUI,无法创建我的 iOS 9+ 应用程序的多个实例。性能与往常一样 - 所有这些都是 CoreImage 实时更新的自定义过滤器 - 而且,对我来说?如果在视图层次结构中有一些与场景相关的操作系统相关的杂物,那么如果不支持场景就没有实际意义。 (最后,是的,我仍然有点担心。但它也是 beta 5。)希望你有一个很好的备份,可以重现我所看到的。 谢谢。我怀疑它在生命周期内。我会花时间调试我的应用程序。每当我发现它以帮助处于类似情况的任何人时,我都会更新它【参考方案3】:

我使用 dfd 的回答来解决这个问题,但由于我的应用程序使用的是 Objective-C,所以我必须进行一项更改:

在Objective-C中,你要放

@property (strong, nonatomic) UIWindow *window;

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

【讨论】:

【参考方案4】:

好的,我想通了。由于 iOS 13 中 Apple 新的默认卡片演示样式发生了变化,在我的故事板中,从我的初始屏幕切换到我的自定义流程导航控制器默认为新的演示文稿(见下面的屏幕截图)。

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

不知道为什么会这样,因为这是我的应用程序中唯一导致这种情况的地方(相当大的应用程序,所以我必须花一些时间浏览所有情节提要以确保)。

【讨论】:

您的问题询问如何选择不使用场景。这个答案没有提供选择退出场景的解决方案。这不应该是公认的答案。如果您只想避免使用新的卡片式演示文稿,那么您可以在解决该问题的多个重复中找到该答案。 这是一种技术,但实际上您需要处理 AppDelegate 中的代码。您还可以将您的 sceneDelegate 的 modalPresentationMode 设置为 .fullScreen,您永远不必担心更改它。【参考方案5】:

Xcode 12 - Swift 5.3 - iOS 14

从 Xcode 12 开始,在 Swift 5.3 和@main 的帮助下,您可以拥有一个没有SceneDelegate 或事件AppDelegate 的多平台应用程序。只会有一个简单的文件,例如:

import SwiftUI

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

【讨论】:

【参考方案6】:

虽然您希望选择退出它,但有时阻止它找到您的 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

【讨论】:

以上是关于在 iOS 上选择退出 UISceneDelegate/SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

无法在 iOS 8 上选择联系人

无法在 IOS 和 Android 移动设备上选择文件

在真实设备上选择 PDF 时 iOS 文档选择器崩溃

让用户在 iOS 上选择一个电子邮件客户端

仅在 iOS 上选择 <input> 时键盘不显示

在iOS上选择图层中的元素后如何防止缩放?