SwiftUI 基础:@StateObject、@ObservedObject 和 @EnvironmentObject 配合 NavigationPath 管理复杂导航(MVVM 模式)

SwiftUI 基础:使用 @StateObject@ObservedObject@EnvironmentObject 配合 NavigationPath 管理复杂导航(MVVM 模式)

一、目标

在本节中,我们将深入了解 SwiftUI 中的三种状态管理方式:@StateObject@ObservedObject@EnvironmentObject,并学习如何在复杂的应用中使用这些工具来高效管理视图间的数据共享与更新,实现多级页面间的任意跳转,一键返回首页

MVVM模式

二、SwiftUI 状态管理简介

SwiftUI 提供了多种方式来管理状态和数据绑定,这些机制适用于不同的场景:

  • @StateObjectSwiftUI 中用于在视图中拥有和初始化一个 ObservableObject 的属性包装器。当视图重新创建时,@StateObject 保证对象不会被重新初始化,从而确保状态的持久。
  • @ObservedObject用于订阅并监听由其他视图或对象管理的状态,不会拥有该对象,因此适合在子视图中使用。
  • @EnvironmentObject 提供了一种将状态对象注入到整个视图层级的方法,无需显式传递。适用于多个视图共享同一个状态对象的场景

可能会遇到的问题及注意事项

  1. 状态对象未被初始化:
    • 错误:Fatal error: No ObservableObject of type … found
    • 解决方案:确保在父视图中使用 .environmentObject() 注入
  2. 多次初始化对象:
    • 错误:使用 @StateObject 导致意外行为
    • 解决方案:确保只在状态对象的拥有者使用 @StateObject,子视图使用 @ObservedObject
  3. 跨多个视图共享状态:
    - 推荐使用:@EnvironmentObject

三、NavigationPath简介

SwiftUI 中,NavigationPath 是一种用于管理页面导航历史和堆栈的结构体,允许开发者更灵活地控制导航堆栈的状态。
它是 iOS 16 引入的一个重要新特性,与传统的 NavigationLink 相比,NavigationPath 提供了更强大的功能,尤其在处理复杂的导航场景时

主要特点:

  • 动态管理导航堆栈。NavigationPath 可以保存多个页面的导航历史,让开发者能够自由地进行导航堆栈的操作。
  • NavigationStack 。它通常与 NavigationStack 结合使用,通过绑定 NavigationPath 来控制页面的导航历史。NavigationStack 会自动根据 NavigationPath 中的内容来显示相应的视图。
  • 支持类型安全的导航。与传统的 NavigationLink 不同,NavigationPath 允许开发者通过使用不同的目标类型(例如枚举类型)来管理跳转的页面,使得导航更具类型安全性和可维护性。

使用方法,参考官方文档:
NavigationPath使用

四、ViewModel简介

SwiftUI 的开发中,ViewModel 是实现 MVVM(Model-View-ViewModel)设计模式的核心部分,用于管理视图的状态和业务逻辑。它在视图(View)和数据(Model)之间起到桥梁作用,将数据的处理逻辑从视图中抽离出来,使代码更清晰、更易于维护。

1. ViewModel 的作用、优点

  1. 管理状态
    • ViewModel 持有视图需要的所有状态,并通过绑定(Binding)将状态与视图连接。状态发生变化时,SwiftUI 自动更新相关视图
  2. 处理业务逻辑
    - ViewModel 负责封装视图相关的业务逻辑,如网络请求、数据验证等,从而让视图专注于 UI 渲染
  3. 隔离视图和数据
    - ViewModel 解耦了视图与模型(Model),视图无需直接操作模型数据,而是通过ViewModel 获取所需的数据
  4. 便于测试
    - 因为 ViewModel 不依赖于具体的视图,实现单元测试更加方便

2.ViewModel 的特点

  1. 遵循 ObservableObject 协议
    - SwiftUI 的视图与 ViewModel 通信通常依赖 @Published 属性和 ObservableObject 协议
    - 当 ViewModel 中的 @Published 属性值发生变化时,绑定该属性的视图会自动刷新
  2. @StateObject 和 @ObservedObject 配合使用
    - 在视图中,@StateObject 用于初始化 ViewModel@ObservedObject 用于在子视图中共享 ViewModel 的实例

五、具体实践

接下来我们基于节程六对代码进行改造

1. 定义导航目标枚举

为了使用 NavigationPath 来管理页面堆栈,我们首先定义一个 NavigationDestination 枚举,表示可能的跳转目标

/// 定义导航目标,提供页面跳转的数据
/// 使用 `Hashable` 协议使其能够被 NavigationPath 识别
enum NavigationDestination: Hashable {
   
   
    case page1
    case pa
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

函数的彼端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值