SwiftUI中全局EnvironmentObject的使用和注意事项,实现多界面共享数据

SwiftUI的@EnvironmentObject是一个强大的工具,它允许你在多个视图之间共享数据(使用一个可观察对象)。当你有一个复杂的视图层次结构,并且需要在没有直接连接的视图之间共享相同的可观察对象时,它特别有用。

创建ObservableObject协议类

要使用环境对象,首先需要创建一个符合ObservableObject协议的ObservableObject类,这个类将保存我们希望在视图之间共享的数据。并将可以观察的属性使用 @Published 属性包装器声明,不然访问和修改该属性可能会导致app崩溃!例如:

Swift 复制代码
//
//  Model.swift
//  SwiftBook
//
//  Created by song on 2024/7/11.
//

import Foundation

// 创建模型类
class Person: ObservableObject {
    
    @Published var id: Int = 0

    @Published var manList: [Man] = [
        Man(index: 1, name: "王思聪", avator: "xigua", content: "好好"),
        Man(index: 2, name: "王健林", avator: "liulian", content: "你好"),
        Man(index: 3, name: "马云", avator: "taozi", content: "今天"),
        Man(index: 4, name: "马化腾", avator: "default", content: "天气"),
        Man(index: 5, name: "王亮", avator: "juzi", content: "真"),
        Man(index: 6, name: "王伦", avator: "putao", content: "不累"),
    ]
}

// 创建结构体
struct Man: Identifiable {
    var id = UUID()
    var index: Int
    var name: String
    var avator: String
    var content: String
}

引入协议类对象

引入这个全局对象的地方有两个地方需要注意:

1.app入口函数的视图中(app启动的时候要保证全局有这个对象,不然会崩溃)

2.要观察全局对象的页面预览视图中(要保证预览页面可以访问到全局对象,不然会崩溃,无法预览或者修改全局对象的属性。即便你在app入口函数设置了,但是预览模式不会走这个入口函数,所以就没办法使用这个入口函数的全局对象)

页面视图修改和访问全局对象

在页面视图中,可以通过声明的@EnvironmentObject var person: Person对象来访问这个全局对象,并通过person.id = 3 的形式来给属性赋值(注意需要将该属性使用@Published属性包装器声明),而且修改后的值,在另外一个页面视图中也是可以成功访问到的。

注意事项

1.使用前一定要在环境变量中添加一个全局对象.environmentObject(Person())

比如你在当前视图中要使用预览功能预览当前页面,就要给当前页面的#Preview函数中添加

2.即便你在App入口函数中添加了这个对象,但是你却在预览中使用这个全局对象,但是你却没有在预览的视图中添加.environmentObject(Person()),程序依然会报错并崩溃!因为预览模式下没有走App的入口函数,所以视图中就没有这个全局对象

3.如果需要向环境中添加多个对象,则应该添加多个.environmentObject修饰符,一个一个的添加即可。

Swift 复制代码
struct EnvironmentObjectDemo: View {
  @StateObject var gameSettings = GameSettings()
  @StateObject var videoSettings = VideoSettings()

    var body: some View {
      NavigationView {
        ......
      }
      .environmentObject(gameSettings)
      .environmentObject(videoSettings)
   }
}

4.另外如果创建了两个同类型的ObservableObject对象,并且依次添加到环境中去,那么最早添加的那个起作用,后添加的无效

相关推荐
恋猫de小郭15 小时前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨19 小时前
iOS应用网络安全之HTTPS
web安全·ios·https
福大大架构师每日一题21 小时前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
BangRaJun2 天前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈2 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长2 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui
一如初夏丿2 天前
xcode15 报错 does not contain ‘libarclite‘
ios·xcode
杨武博3 天前
ios 混合开发应用白屏问题
ios
BangRaJun3 天前
LNCollectionView
android·ios·objective-c
二流小码农3 天前
鸿蒙元服务项目实战:终结篇之备忘录搜索功能实现
android·ios·harmonyos