由于去除了AppDelegate.swift
和SceneDelegate.swift
,SwiftUI2.0
提供了新的方法来让程序响应系统事件。通过使用@UIApplicationDelegateAdaptor
可以方便的实现之前AppDelegate.swfit
中提供的功能:
https://github.com/JWAutumn/SwiftUIAppLifeCycle
应用程序生命周期:SwiftUI 2 在 WWDC 2020上的发布,苹果引入了一个新的应用程序生命周期(App
)。替代了 AppDelegate
。
在 App
里,苹果提供了一个新的 API:ScenePhase
SwiftUI 中跟踪应用程序的状态,可以用 @Environment
属性包装器来获取当前值,用 .onChange(of:perform:)
监听更改。除了在App中监听,应用里的其他位置也可以使用这种监听方式。
import SwiftUI
/*
结构的body属性返回一个或多个场景,这些场景又提供了要显示的内容。该@main属性标识应用程序的入口点。
*/
@main
struct DriverHomeSwiftUIApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@Environment(\.scenePhase) var scenePhase
var body: some Scene {
WindowGroup {
ContentView().environmentObject(User())
//获取到 url 后处理
.onOpenURL(perform: { url in
print("Received URL: \(url)")
})
}.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("Application is active")
case .inactive:
print("Application is inactive")
case .background:
print("Application is background")
default:
print("unexpected value.")
}
}
}
class AppDelegate:NSObject,UIApplicationDelegate{
//swiftUI 2只有这个还有效果,其他的生命周期方法都失效,用上面的onchage代替。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("launch")
return true
}
}
}
swiftUI 1 的做法:不使用了
import SwiftUI
/*
结构的body属性返回一个或多个场景,这些场景又提供了要显示的内容。该@main属性标识应用程序的入口点。
*/
@main
struct DriverHomeSwiftUIApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(User())
}
}
class AppDelegate:NSObject,UIApplicationDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("launch")
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
print("变的活跃")
}
func applicationWillEnterForeground(_ application: UIApplication) {
print("即将进入前台")
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("进入后台")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("deviceToken")
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
print("openurl")
return true
}
func applicationWillTerminate(_ application: UIApplication) {
print("程序关闭")
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
print("变得活跃")
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
print("进入后台")
}
}
}
view的生命周期:
SwiftUI在body的闭包只执行一次,等价于UIKit的viewDidLoad()
方法。UIKit的 viewDidAppear()
和 viewDidDisappear()
等价于SwiftUI的方法onAppear()
和 onDisappear()。
@EnvironmentObject var user: User
@Environment(\.scenePhase) private var scenePhase
var body: some View{
List{
headerSection
ForEach(Persons,id: \.self) {person in
VStack {
NavigationLink(destination: one()){
Text(user.name)
}
}
}
}.onAppear {
print("view出现")
}.onDisappear {
print("消失")
}.onHover { (s) in
print("\(s)")
}.onChange(of: scenePhase, perform: { value in
if value == .active {
print("Application view is active...")
}
})
}
接收应用生命周期改变的通知:
SwiftUI可以检测您的应用何时移至后台(即用户何时返回主屏幕),何时回到前台,用户何时截取屏幕截图等等。这些全部由 Notification Center 提供支持,Notification Center 是 Apple 内部消息系统的API名称,该API使系统可以在事件发生时通知我们,还可以使我们在代码的不同部分之间发布消息。
当您的应用开始移至后台时,通知中心会发布一条名为UIApplication.willResignActiveNotification
的消息;要使用它,我们需要让 Notification Center 为该通知创建一个发布者,然后附加我们想要的任何工作。我们会收到作为闭包参数的实际消息。
VStack {
Text("Hello, World!")
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
print("即将进入后台")
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
print("即将进入前台")
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.userDidTakeScreenshotNotification)) { _ in
print("用户截屏了")
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)) { _ in
print("已经进入后台")
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
print("已经进入前台")
}.onReceive(NotificationCenter.default.publisher(for: UIApplication.willTerminateNotification)) { _ in
print("程序将要销毁")
}
}