Swiftui 不接收场景数据库更改
我正在尝试执行一些我以前放在我的应用程序委托中的代码,例如在进入后台时保存我的托管对象上下文。我将调用放在ScenePase的Swiftui 不接收场景数据库更改,swiftui,Swiftui,我正在尝试执行一些我以前放在我的应用程序委托中的代码,例如在进入后台时保存我的托管对象上下文。我将调用放在ScenePase的.onChange中,但没有得到任何结果。以下是一个示例项目: import SwiftUI @main struct PhaseApp: App { @Environment(\.scenePhase) private var scenePhase var body: some Scene { WindowGroup {
.onChange
中,但没有得到任何结果。以下是一个示例项目:
import SwiftUI
@main
struct PhaseApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
Text("Hello, world.")
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("Active")
case .background:
print("Background")
case .inactive:
print("Inactive")
@unknown default: break
}
}
}
}
每当我按下Home键或轻触应用程序时,我希望在模拟器或测试设备上获得打印命令,但什么也没有发生。使用内部场景根视图(通常是
ContentView
)
使用Xcode 12/iOS 14进行测试
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
TestView()
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print(">> your code is here on scene become active")
case .inactive:
print(">> your code is here on scene become inactive")
case .background:
print(">> your code is here on scene go background")
default:
print(">> do something else in future")
}
}
}
}
您可以使用以下扩展名:
public extension View {
func OnScenePhaseChange(phase: ScenePhase, action: @escaping () -> ()) -> some View
{
self.modifier( OnScenePhaseChangeModifier(phase: phase, action: action) )
}
}
public struct OnScenePhaseChangeModifier: ViewModifier {
@Environment(\.scenePhase) private var scenePhase
public let phase: ScenePhase
public let action: () -> ()
public func body(content: Content) -> some View {
content
.onChange(of: scenePhase) { phase in
if (phase == phase) {
action()
}
}
}
}
最终用途:
ContentView()
.OnScenePhaseChange(phase: .active) { print("scene activated!") }
.OnScenePhaseChange(phase: .background) { print("scene backgrounded!") }
.OnScenePhaseChange(phase: .inactive) { print("scene inactive!") }
我一直在使用Xcode 12 beta 3和iOS/iPadOS 14 beta 3进行测试,下面是我的发现。请注意,这其中很多都涉及到支持多个窗口,但是“SwiftUI生命周期”项目默认启用该功能,因此我怀疑您已经激活了它。在我最初的案例中,我将一个现有的SwiftUI应用程序从一个
SceneDelegate
移植到使用新的app
struct,因此我已经有了多个窗口支持
以下是我在新测试应用程序中使用的测试视图
:
struct ContentView:View{
@环境(\.scenePhase)私有变量scenePhase
var body:一些观点{
文本(“你好,世界!”).padding()
.onChange(of:scenePhase){phase in
开关相位{
案例.背景:
打印(“阶段更改:查看输入的背景”)
案件.现行:
打印(“阶段更改:视图输入激活”)
案例.非活动:
打印(“阶段更改:视图输入为非活动状态”)
@未知默认值:
打印(“阶段更改:视图进入未知阶段”)
}
}
}
}
(我在应用程序
和场景
中有相同的代码,但它们从不打印任何内容。)
应用程序
、场景
或视图
中声明onChange
。在任何情况下,我都看不到应用程序
或场景
级别的版本执行过,而且视图
级别的版本似乎没有完全正确执行
视图
级别关闭。(完全公开,这款iPod Touch仍在运行beta 2,但我认为这无关紧要。一旦我将其更新到b3,如果有关系,我会在这里提及。)编辑(这确实很重要。)
在不支持多个窗口(第7代iPod Touch)的运行beta 2的硬件上,我看到应用程序进入后台,回到前台,等等。在每次应用发布时,我都会看到“查看输入的活动”打印
TL;博士:
我认为您应该能够从
视图中看到大多数场景库更改,但您将错过在iPad或模拟器上启动的初始应用程序。希望它们能像预期的那样在稍后的beta版中出现在App
和Scene
对象中?由@Asperi给出的答案确实有效。但是场景扩展中有一个例子,在WindowGroup上调用onChange操作符。所以,我认为这是一个错误。如果我像这样使用它,所有的状态都会被触发!按照你在代码中写它们的顺序。我想如果(相位==相位)可能是问题所在。我重新命名了一个,效果更好。