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对象,并且依次添加到环境中去,那么最早添加的那个起作用,后添加的无效

相关推荐
S0linteeH4 小时前
iOS 18 正式上線,但 Apple Intelligence 還要再等一下
ios
S0linteeH5 小时前
iOS 18 新功能:控制中心大變身!控制項目自由選配
ios·iphone
AI智东西5 小时前
150+个流行的Instagram标签(及如何找到并正确使用它们)
人工智能·ios·chatgpt·iphone
奇客软件6 小时前
iPhone 上丢失了重要的联系人?如何恢复已删除的 iPhone 联系人
windows·深度学习·ios·电脑·笔记本电脑·iphone·学习方法
ehviwer2314 小时前
MathType7.9绿色和谐版激活补丁包下载
android·macos·ios·cocoa·媒体
ios and Android15 小时前
【iOS逆向与安全】frida-trace命令大全
开发语言·javascript·ios
Johnny Tong16 小时前
iOS 18 适配 Xcode 16 问题
ios·cocoa·xcode
awonw16 小时前
[网络][CISCO]CISCO IOS升级
网络·ios
一只不会编程的猫18 小时前
高德地图绘图,点标记,并计算中心点
开发语言·ios·swift
CV_CodeMan2 天前
uniapp组件uni-datetime-picker选择年月后在ios上日期不显示
前端·ios·小程序·uni-app