SwiftUI — 生命周期 onAppear 等

在 SwiftUI 中,生命周期管理是一项重要功能,开发者需要在某个视图的特定阶段执行代码逻辑,例如当视图出现、消失、弹出回到页面时响应事件。除了 onAppearonDisappear 之外,SwiftUI 提供了一些其他的生命周期管理相关修饰符和工具。

以下是与生命周期相关的函数或修饰符的完整清单及其使用场景:


1. onAppear #

  • 描述:
    当视图 第一次 出现在屏幕上时触发一次,并且每次重新进入页面时也会调用。
  • 使用场景:
    初始化一个视图时加载数据、开始网络请求、设置计时器等。

示例: #

struct OnAppearExampleView: View {
    var body: some View {
        Text("Hello, SwiftUI!")
            .onAppear {
                print("View has appeared!")
            }
    }
}

2. onDisappear #

  • 描述:
    当视图即将从屏幕中 消失(或被销毁)时触发。
  • 使用场景:
    清理资源、取消任务、销毁计时器或停止某些活动。

示例: #

struct OnDisappearExampleView: View {
    var body: some View {
        Text("Goodbye, SwiftUI!")
            .onDisappear {
                print("View is about to disappear!")
            }
    }
}

3. task #

  • 描述:
    在指定上下文中运行异步任务,通常在视图 首次出现 时触发。适用于需要异步操作的场景,比如数据加载。
  • 使用场景:
    异步的初始化任务,如通过网络请求加载数据。

示例: #

struct TaskExampleView: View {
    var body: some View {
        VStack {
            Text("Loading...")
        }
        .task {
            await fetchData() // 异步数据加载
        }
    }

    func fetchData() async {
        print("Fetching data...")
        try? await Task.sleep(for: .seconds(2)) // 模拟网络加载
        print("Data fetched!")
    }
}

4. onChange(of:) #

  • 描述:
    监听某个数据的状态变化。当绑定值发生更改时触发。
  • 使用场景:
    响应状态或变量的实时变化,比如监控表单输入更新、设置动画、操作应用逻辑。

示例: #

struct OnChangeExampleView: View {
    @State private var name: String = ""

    var body: some View {
        TextField("Enter your name", text: $name)
            .onChange(of: name) { newValue in
                print("Name changed to: \(newValue)")
            }
    }
}

注意: #

onChange(of:) 是值变化监听器,不是视图生命周期事件管理器,尽管它可以很灵活地在状态变化时触发逻辑。


5. ScenePhase 生命周期监控 #

  • 描述:
    使用 @Environment(\.scenePhase) 环境变量监控应用程序的生命周期状态(后台、活跃或非活跃状态)。
  • 使用场景:
    管理应用状态,比如在后台保存数据、暂停任务或激活任务。

三种状态值: #

  1. active 应用处于前台并活动。
  2. inactive 应用处于前台但不是活动状态(如接收到来电时)。
  3. background 应用已进入后台。

示例: #

import SwiftUI

struct ScenePhaseExample: View {
    @Environment(\.scenePhase) private var scenePhase

    var body: some View {
        Text("App Lifecycle Example")
            .onChange(of: scenePhase) { newPhase in
                switch newPhase {
                case .active:
                    print("App is active")
                case .inactive:
                    print("App is inactive")
                case .background:
                    print("App is in background")
                default:
                    break
                }
            }
    }
}

6. onReceive #

  • 描述:
    监听 Publisher 的事件(例如 Timer 或其他 Combine 流),当 Publisher 发送数据时触发。
  • 使用场景:
    适合倒计时、网络状态变化、外部事件变化等。

示例: #

struct OnReceiveExampleView: View {
    @State private var currentTime = Date()

    let timer = Timer.publish(every: 1.0, on: .main, in: .common).autoconnect()

    var body: some View {
        Text("Current Time: \(currentTime)")
            .onReceive(timer) { time in
                currentTime = time // 更新时间
            }
    }
}

7. Environment 定制视图环境(类似生命周期) #

  • 描述:
    通过 @Environment@EnvironmentObject 管理一些全局环境值的切换,例如监控竖屏与横屏的切换、暗黑模式等。
  • 使用场景:
    检测系统环境(如通知设置、配色主题)或自定义共享的数据环境。

示例:检测屏幕方向 #

struct OrientationExampleView: View {
    @Environment(\.horizontalSizeClass) var horizontalSizeClass

    var body: some View {
        Text(horizontalSizeClass == .compact ? "Portrait" : "Landscape")
            .onAppear {
                print("View loaded in \(horizontalSizeClass == .compact ? "Portrait" : "Landscape")")
            }
    }
}

8. Custom Task Cancellation (自定义任务管理) #

SwiftUI 中 Task 的生命周期会跟随视图销毁。如果需要手动控制任务取消(例如处理某些长时间运行的任务),可以使用 Task.handle

示例: #

struct LongOperationExample: View {
    @State private var counter = 0
    @State private var task: Task<Void, Never>? = nil

    var body: some View {
        VStack {
            Text("Counter: \(counter)")

            Button("Start Counting") {
                task = Task {
                    while !Task.isCancelled {
                        try? await Task.sleep(for: .seconds(1))
                        counter += 1
                    }
                }
            }

            Button("Stop Counting") {
                task?.cancel() // 手动取消任务
            }
        }
    }
}

总结对比 #

触发器描述应用场景
onAppear当视图首次出现在屏幕上初始化数据、加载任务
onDisappear当视图从屏幕上消失停止计时器、清理资源
taskonAppear 时运行异步任务(更适合异步代码)执行异步操作,如网络加载
onChange(of:)监听某个值的变化动态响应绑定值的更新
scenePhase监听应用级别的生命周期变化,例如 active, backgroundinactive 状态应用状态管理(保存、恢复任务等)
onReceive监听 Combine 发布者(Publisher),如 Timer 和通知流定时任务、外部事件处理
Environment 或 Dynamic使用环境值来检测系统(如屏幕方向、配色模式)根据环境自适应视图显示
取消任务(Task手动取消正在运行的长期任务精细控制长时间任务的终止

以下是与 SwiftUI 生命周期管理相关的函数的官方 Apple 文档链接: #


1. onReceive #


2. onAppear #


3. onDisappear #


4. onChange(of:) #


5. ScenePhase 监控 #


6. task #

本文共 1616 字,上次修改于 Dec 30, 2024