SwiftUI中EnvironmentObject使用中,直接修改数据源的原值的方法

这篇具有很好参考价值的文章主要介绍了SwiftUI中EnvironmentObject使用中,直接修改数据源的原值的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Swift中有几种引用,一个通过@Binding  var Param来引用原变量的值,在子函数或子View中修改 Param,但我们也经常使用@EnvironmentObject来引用全局数据。

例如:

struct TestEnvSubView: View {
   
    @EnvironmentObject var globalData : GlobalData
   
    @Binding var firstID:Int
    @Binding var secondID:Int
     
    @State private var showEditDetail = false
     
        
        var body: some View {
            @State var myData = globalData[firstID][secondID]
                VStack {
 
                    Button(action: {
                        myData.Name = "test"
                        self.showEditDetail = true
                    })
                    {
                        Text(myData.Name)
                    }
 
                }
                
        }

}

在这个例子中,我们通过定义
@EnvironmentObject var greenhouseData : GreenhouseData

来引用全局的数据GreenhouseData,当然在上一层View中,应该有加载 .environmentObject(greenhouseData),不然在子View也加载不到数据。

struct testPlant: Identifiable {
    let id = UUID()
    var Name: String
}
class GlobalData: ObservableObject {
    @Published var globalData: [[Greenhouse]] = [[]]  
    init() {
         
        let globalData1 = [testPlant(Name: "Plant 1"), testPlant(Name: "Plant 2")]
        let globalData2 = [testPlant(Name: "Plant 3"), testPlant(Name: "Plant 4")]
        globalData = [globalData1, globalData2]
    }
     

}
struct TestEnvParentView: View {
    
    @StateObject var globalData = GlobalData()
    
    
    @State private var firstID = 0
    @State private var secondID = 0
     
    @State private var showDetail = false
   
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
            VStack() {
                
                        Spacer()
                        Button(action: {
                            self.showDetail = true
                        })
                        {Text("click")}
                            
                        }
                        Spacer()
                    }
                }
            }.sheet(isPresented: $showDetail){
                TestEnvSubView(firstID:$firstID,secondID:$secondID)
   
            }
            .environmentObject(globalData)
         
    }
    
}

但发现点击Button后,Text(myData.Name)没有变化,我在想不是@EnvironmentObject来引用全局数据,怎么就没更改呢。

其实是因为:@State var myData = globalData[firstID][secondID]是一个复制变量,并不是原globalData[firstID][secondId]的副本的引用,而修改myData,是不会对myData影响的。

第一步:我想是不是,可以直接操作globalData[firstID][secondID],

修改下代码为:

var body: some View {
        @State var myData = globalData.[firstID][secondID]
            VStack {

                Button(action: {
                    self.globalData.[firstID][secondID].Name = "test"
                    self.showEditDetail = true
                })
                {
                    Text(myData.Name)
                }

            }
            
    }

点击Button后,Text(myData.Name)变化了,并且返回上一层View也变化了。

这直接操作globalData[firstID][secondID]是成功的!!!

但是我感觉这么直接操作globalData[firstID][secondID],太繁琐了,能不能用一个变量赋值,就简单点。

第二步:我就想用@State var myData = globalData.[firstID][secondID]修改为

var myData = globalData[firstID][secondID],但运行后,@State var myData = globalData.[firstID][secondID].Name没有变化!这是什么鬼。

分析:

var myData = globalData[firstID][secondID], 应该是 globalData[firstID][secondID]的一个复制品,

第三步:使用var myData = $globalData[firstID][secondID]来引用原数据,再直接wrappedValue访问,并修改它的值。

var body: some View {
         var myData = $globalData.[firstID][secondID]
            VStack {

                Button(action: {
                    myData.wrappedValue.Name = "test"
                    self.showEditDetail = true
                })
                {
                    Text(myData.wrappedValue.Name)
                }

            }
            
    }

发现是成功的!

总结:为什么不同的方法访问globalData[firstID][secondID],修改都不行呢, 这里总结下:

1、@State myData = globalData[firstID][secondID]

这个方式使用了@State属性包装了myData变量,以便你可以在视图中使用它,并在需要时更新它。当你使用这种方式时,myData变量的值会在视图重绘时被重新初始化。因此,如果你想要在视图之间共享数据,你应该使用其他方法。

当你将数据源中的globalData数组中的某个元素存储在@State属性中时,它会创建一个myData变量的本地副本,而不是引用原始数据源中的testPlant实例。因此,对myData变量的任何更改都不会影响原始数据源中的testPlant实例。

2、let myData = globalData[firstID][secondID].wrappedValue

这个方式使用了wrappedValue属性来获取绑定属性的实际值,并将其存储在myPlant变量中。当你使用这种方式时,myData变量存储的是数据源中的testPlant实例的一个副本,而不是一个绑定属性的引用。因此,如果你修改myData变量的值,它不会更新到数据源中。

3、let myData = $globalData[firstID][secondID]

----唯一可以在视图中直接修改globalData[firstID][secondID].原值的方法。

这个方式使用了$符号来获取绑定属性的引用,以便你可以在视图中修改数据源中的属性或变量。当你使用这种方式时,myData变量存储的是一个绑定属性的引用,你可以使用它来更新数据源中的属性或变量。但是,当你访问myData变量的值时,它返回的是绑定属性的实际值,而不是绑定属性的引用,需要使用 myData.wrappedValue.Value来修改原值:

myData.wrappedValue.Name = "test"

4、let myData = $globalData[firstID][secondID].wrappedValue

这个方式结合了前两种方式的特点,使用了$符号来获取绑定属性的引用,并使用wrappedValue属性来获取绑定属性的实际值。当你使用这种方式时,myData变量存储的是数据源中的testPlant实例的一个副本,而不是一个绑定属性的引用

最后:还有一个问题:

使用let myData = $globalData[firstID][secondID]时,为什么一定用myData. wrappedValue.Name = newValue 修改,而不是myData.Name = newValue来修改?

原因是:

使用 myData.wrappedValue.Name = newValue 来修改 globalData 对象的属性,而不是使用 myData.Name = newValue。这是因为 myData 变量实际上是一个 Binding 对象,而 Name 属性是 testPlant 对象的一个属性。如果你直接使用 myData.Name = newValue 来修改属性,编译器会报错,因为 Binding 对象没有 Name 属性文章来源地址https://www.toymoban.com/news/detail-462700.html

到了这里,关于SwiftUI中EnvironmentObject使用中,直接修改数据源的原值的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot多数据源使用

    在工作上有一个新项目,现在需要获取旧项目的用户信息、积分的操作等等,所以需要调用另外一个项目的数据库,所以我们可以配置多数据源。 yml版本  properties版本 在impl类上加注解@DS(\\\"master\\\"),master为配置的master名字 调用方法  获取结果  在impl类上加注解@DS(\\\"slave_1\\\"),

    2024年02月11日
    浏览(38)
  • qml使用QAbstractListModel作为数据源

    在日常开发中界面为了快速并且炫酷,大家可能会选择qml作为主体。但是后台数据的提供还是用qt c++的实现,MVC中即可用Model进行。例如:QAbstractListModel 一般的使用只实现下面三个函数即可支撑qml中的交互: 但是想要一些其他的功能,就需要自己去实现了! 一、例如想进行

    2024年02月11日
    浏览(34)
  • Nacos2.2使用PostgreSQL数据源插件存储数据手把手教程

    Nacos2.2在2022年的12月份正式发布了,该版本可以让开发者开发支持PostgreSQL数据库的插件,从而实现将配置信息存储到PostgreSQL中。 本文基于自己开发的PostgreSQL数据源插件进行说明,希望可以帮助到大家。 数据源插件开源仓库地址: https://github.com/wuchubuzai2018/nacos-datasource-exte

    2024年02月03日
    浏览(36)
  • 使用脚本,直接修改注册表的值---设置win10背景色(保护色)

    目录 ■修改注册表(手动) ■修改注册表(脚本化) ・修改 ・恢复 ■其他(注册表图片) === 前言,媳妇上班,不会修改win10系统背景色(她想弄成保护色),提供个脚本,一键修改。 └window ⇒207 232 204 └Window ⇒caeace ・修改 新建一个xxx.reg文件,把下面内容复制进去 ・恢

    2024年02月12日
    浏览(47)
  • java serverlets使用数据源连接oracle数据库,并执行查询操作代码

    package chap03; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Statement; import java.util.*; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Namin

    2024年02月08日
    浏览(51)
  • Spring | 基于SpringBoot的多数据源实战 - 使用seata实现多数据源的全局事务管理

    在软件开发中, 多数据源 的应用越来越普遍,特别是在 微服务架构 和 业务模块化 的场景下。多数据源能够让不同的业务模块和微服务拥有各自独立的数据存储,大大提高了系统的灵活性和可维护性。本文将深入探讨多数据源的配置和实施,以及在 Spring Boot 环境下,如何通

    2024年02月07日
    浏览(60)
  • 单个数据源与多数据源使用mybatisplus分页插件total一直为0的解决办法

    1. 注册分页插件( 不注册分页插件total也是0) : 注意:如果是 单数据源 此时分页插件能正常使用,而 如果是多数据源 ,那么就必须添加以下内容,否则分页时查询总数total还是0 2. 多数据源定义: 重点就是以下两行:  Interceptor[] interceptors = new Interceptor[] { mybatisPlusInterc

    2024年04月25日
    浏览(36)
  • dolphinscheduler 3.0.1 数据源中心及使用

    🔼上一集:dolphinscheduler 3.0.1数据质量 *️⃣主目录:dolphinscheduler 3.0.1功能梳理及源码解读 🔽下一集:dolphinscheduler 3.0.1 监控中心(上):服务管理 2.0常见数据库都支持,MySQL、PostgreSQL、Oracle、SQLServer、Hive,这样都验证过,都支持,Spark是不支持的,2.0没开发spark数据库组件,

    2023年04月08日
    浏览(39)
  • springboot使用DynamicDataSource来动态切换数据源

    DynamicDataSource是一个数据源路由器,可以根据上下文动态选择数据源。可以在每个请求或线程中将数据源设置为当前需要使用的数据. 创建一个 DynamicDataSource 类,它继承自 AbstractRoutingDataSource 。在该类中重写**determineCurrentLookupKey()**方法,该方法返回一个字符串,用于指示当前

    2024年02月05日
    浏览(43)
  • docker版jxTMS使用指南:数据源简述

    本文讲解4.2版jxTMS的数据源,整个系列的文章请查看:docker版jxTMS使用指南:4.2版升级内容 docker版本的使用,请参考docker版jxTMS使用指南 4.0版jxTMS的说明,请查看:4.0版升级内容 4.0版jxTMS主要是通过MQTT进行采集。这种采集模式是前端主动的、定时的向接口机进行推送,但对于

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包