问题描述
我目前正在使用SwiftUI开发应用程序。
我想在视图出现时使用一种方法。
对于下面附带的代码,在启动应用并在页面之间进行一些转换时,我可以使用print
方法。
但是当我重新打开应用程序时,我想使用print
方法,如下所示:
在这种情况下我该如何做?
代码如下:
import SwiftUI
struct ContentView: View {
@State private var selection = 0
var body: some View {
TabView(selection: $selection){
Text("First View")
.onAppear(){
print("First")
}
.tabItem {
Text("First")
}
.tag(0)
Text("Second View")
.tabItem {
Text("Second")
}
.tag(1)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
添加:
我找到了一种方法,可以使用sceneWillEnterForeground
中的sceneWillResignActive
或SceneDelegate.swift
将应用程序从后台变为前台使用
但是在这种情况下,当应用程序通过SecondView成为前景时,它也可以正常工作。 而且我想修改代码以仅在应用程序通过FirstView成为前台时起作用。
有什么办法吗?
SceneDelegate.swift
func sceneDidBecomeActive(_ scene: UIScene) {
print("BecomeActive")
}
func sceneWillEnterForeground(_ scene: UIScene) {
print("Foreground")
}
Xcode:版本11.7
Swift:Swift 5
解决方法
您可以使用@EnvironmentObject
来跟踪应用程序状态(通过观察通知):
class AppState: ObservableObject {
@Published var isActive = true
private var observers = [NSObjectProtocol]()
init() {
observers.append(
NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification,object: nil,queue: .main) { _ in
self.isActive = true
}
)
observers.append(
NotificationCenter.default.addObserver(forName: UIApplication.willResignActiveNotification,queue: .main) { _ in
self.isActive = false
}
)
}
deinit {
observers.forEach(NotificationCenter.default.removeObserver)
}
}
您需要在SceneDelegate中创建一次(仅一次),并将其作为@EnvironmentObject
传递到ContentView:
let appState = AppState()
let contentView = ContentView().environmentObject(appState)
现在,您可以在所需的任何视图中使用@EnvironmentObject
:
struct FirstView: View {
@EnvironmentObject var appState: AppState
var body: some View {
Text("First View,isActive: \(appState.isActive.description)")
}
}