【iOS】SwiftUI状态管理

@State @ObservedObject @StateObject 的使用

import SwiftUI

class CountModel: ObservableObject {
    @Published var count: Int = 0 // 通过 @Published 标记的变量会触发视图更新

    init() {
        print("TimerModel initialized at \(count)")
    }
}

struct ContentView: View {
    @State private var count: Int = 0 // 声明一个状态变量

    @ObservedObject private var model = CountModel() // 观察一个可观察对象

    @StateObject private var model2 = CountModel()

    var body: some View {
        VStack {
            Text("Parent Count: \(count)")

            Button {
                count += 1 // 修改可观察对象中的变量
            } label: {
                Text("parent count")
            }

            Text("parent model Count \(model.count)")
            Button {
                model.count += 1 // 修改可观察对象中的变量
                model2.count += 1 // 修改可观察对象中的变量

            } label: {
                Text("model count")
            }

            ChildView(count: $count, model: model, model2: model2) // 通过绑定将状态传递给子视图
        }
    }
}

struct ChildView: View {
    @Binding var count: Int // 子视图中的绑定变量

    @ObservedObject var model: CountModel
    @ObservedObject var model2: CountModel

    var body: some View {
        Button(action: {
            count += 1 // 修改绑定的状态
        }) {
            Text("Child \(count) modelcount: \(model.count) model2 count \(model2.count)")
        }
    }
}

#Preview {
    ContentView()
}

在这里插入图片描述
使用@ObservedObject的对象直接传递给子类的效果和@StateObject虽然可以达到同样的效果,但是不安全。
在这里插入图片描述

@EnvironmentObject @Environment @AppStorage

@EnvironmentObject 需要将数据从父类传递给子类;
@AppStorage 全局可用,使用UserDefaults也可以修改数据;


// 可观察对象,用来存储应用的状态
class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
}

struct ContentView2: View {
    @EnvironmentObject var userSettings: UserSettings // 从环境中获取共享的数据

    @Environment(\.appTheme) var appTheme
    
    @AppStorage("isDarkMode") var isDarkMode: Bool = false

    var body: some View {
        VStack {
            Text("Hello, \(userSettings.username) isDarkMode: \(isDarkMode)")
                .background(appTheme.backgroundColor) // 使用环境中传递的主题背景色
                .foregroundColor(appTheme.textColor) // 使用环境中传递的主题文字色
            Button("Change Username in Content") {
                userSettings.username = "Content" // 修改用户名,视图会自动更新
                isDarkMode.toggle()
            }
        }
        .padding()
    }
}

struct AnotherView: View {
    @EnvironmentObject var userSettings: UserSettings
    
    // @AppStorage
    // @AppStorage 是一种属性包装器,用于将数据存储到应用的 UserDefaults 中,并且能够使得数据在视图间保持同步。
    // 它允许你轻松地从 UserDefaults 获取和存储数据,同时自动处理视图的更新。。
    // 它非常适合在应用程序中持久化小型设置或状态,如主题、语言选择等。当 UserDefaults 中的数据发生变化时,视图会自动重新渲染。
    @AppStorage("isDarkMode") var isDarkMode: Bool = false

    var body: some View {
        VStack {
            Text("AnotherView Hello: \(userSettings.username) isDarkMode: \(isDarkMode)")
            Button("Change Username in Another View") {
                userSettings.username = "Another"
                UserDefaults().set(true, forKey: "isDarkMode")
            }

            ThreeLevelView()
        }
    }
}

struct ThreeLevelView: View {
    @EnvironmentObject var userSettings: UserSettings

    var body: some View {
        VStack {
            Text("ThreeLevelView Hello: \(userSettings.username)")
            Button("Change Username in ThreeLevelView") {
                userSettings.username = "Three Level"
            }
        }
    }
}

struct ParentView: View {
    @EnvironmentObject var userSettings: UserSettings

    var body: some View {
        VStack {
            ContentView2()
            AnotherView()
        }
    }
}

struct HomePageView: View {
    @StateObject private var userSettings = UserSettings()

    let lightTheme = AppTheme(backgroundColor: .white, textColor: .black)
    let darkTheme = AppTheme(backgroundColor: .red, textColor: .white)

    @Environment(\.colorScheme) var colorScheme1 // 获取当前的颜色模式
    @Environment(\.horizontalSizeClass) var sizeClass // 获取当前设备的横向布局类

    var body: some View {
        VStack {
            Text("HomePage Hello: \(userSettings.username)")
            Button("Change Username in HomePage") {
                userSettings.username = "HomePage"
            }
        }
        // @Environment
        // @Environment属性包装器用于从视图的环境中获取系统提供的或由父视图注入的共享数据,而不需要显示地通过属性传递数据。
        // 它能让你访问与当前环境相关的信息,并在视图中进行响应式更新。
        // 基本语法: @Environment(\.key) var value@Environment(\.key) var value
        // key:系统环境值的键或自定义的环境键,用来标识要获取的环境数据.
        //  value:存储在环境中的实际值,可以是任何类型.
        // SwiftUI 提供了一些常用的系统级别的环境数据,比如: 当前的颜色模式,设备的横向布局类
        ParentView().environmentObject(userSettings).environment(\.appTheme, darkTheme)
    }
}

struct AppTheme {
    var backgroundColor: Color
    var textColor: Color
}

struct AppThemeKey: EnvironmentKey {
    // 为这个环境键提供默认值
    static let defaultValue: AppTheme = .init(backgroundColor: .red, textColor: .yellow)
}

extension EnvironmentValues {
    var appTheme: AppTheme {
        get { self[AppThemeKey.self] }
        set { self[AppThemeKey.self] = newValue }
    }
}

#Preview {
    HomePageView()
}

其它链接:
SwiftUI 中的状态管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/972848.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

组合总和力扣--39

目录 题目 思路 剪枝优化 代码 题目 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的…

基于知识图谱的问答系统:后端Python+Flask,数据库Neo4j,前端Vue3(提供源码)

基于知识图谱的问答系统:后端PythonFlask,数据库Neo4j,前端Vue3 引言 随着人工智能技术的不断发展,知识图谱作为一种结构化的知识表示方式,逐渐成为问答系统的重要组成部分。本文将介绍如何构建一个基于知识图谱的问答…

【第四届网络安全、人工智能与数字经济国际学术会议(CSAIDE 2025】网络安全,人工智能,数字经济的研究

重要信息 会议官网:www.csaide.net 会议时间:2025年3月7-9日 会议地点:马来西亚-马来西亚理工大学新山校区(线上线下混合) 简介 过去几年,数字经济蓬勃发展,已成为全球经济增长的驱动力。…

VSCode AI提效工具,通义灵码前端开发体验

安装 安装依旧很简单,vs code拓展插件中搜索就出来了,记住下边这个图标。 亮点 新接入了deepseek-v3\deepseek-r1模型,不仅支持智能问答,而且增加了AI程序员,可以直接按照完成编码任务,修改优化代码&am…

Ansys Zemax | 使用衍射光学器件模拟增强现实 (AR) 系统的出瞳扩展器 (EPE):第 2 部分

附件下载 联系工作人员获取附件 在 OpticStudio 中使用 RCWA 工具为增强现实(AR)系统设置出瞳扩展器(EPE)的示例中,首先解释了 k空间中光栅的规划,并详细讨论了设置每个光栅的步骤。 介绍 本文提供了多…

深度学习04 数据增强、调整学习率

目录 数据增强 常用的数据增强方法 调整学习率 学习率 调整学习率 ​调整学习率的方法 有序调整 等间隔调整 多间隔调整 指数衰减 余弦退火 ​自适应调整 自定义调整 数据增强 数据增强是通过对训练数据进行各种变换(如旋转、翻转、裁剪等)&am…

微软宣布 Windows 11 将不再免费升级:升级需趁早

大家都知道如果你现在是Windows 10 系统,其实可以免费升级到正版 Windows 11,只要你的电脑配置满足 TPM2.0要求。 而最近微软已经公布了 Windows 10 的最后支持时间,也就是今年10月14日,在这之后微软将不再对Windows 10负责&#…

【Spring详解三】默认标签的解析

三、默认标签的解析 Spring的标签中有 默认标签和 自定义标签,两者的解析有着很大的不同,这次重点说默认标签的解析过程。 DefaultBeanDefinitionDocumentReader.class 默认标签的解析是在 DefaultBeanDefinitionDocumentReader.parseDefaultElement()函…

位运算,双指针,二分,排序算法

文章目录 位运算二进制中1的个数题解代码我们需要0题解代码 排序模版排序1题解代码模版排序2题解代码模版排序3题解代码 双指针最长连续不重复子序列题解代码 二分查找题解代码 位运算 1. bitset< 16 >将十进制数转为16位的二进制数 int x 25; cout << bitset<…

ArkTS与ArkUI深度解析:鸿蒙应用开发的未来之路

文章目录 **1. ArkTS与ArkUI概述****1.1 什么是ArkTS&#xff1f;****核心特性** **1.2 什么是ArkUI&#xff1f;****核心特性** **1.3 二者的核心优势** **2. ArkTS语言基础****2.1 语法特性与TypeScript的对比****2.2 变量与类型系统****基本类型****联合类型与类型别名** **…

关于 BK3633 上电时受串口 UART2 影响而无法启动的问题说明

1. 问题描述 BK3633 SDK 版本&#xff1a;BK3633_DesignKit_V06_2310 使用 BK3633 UART2 与指纹模块进行通讯&#xff0c;为了降低功耗&#xff0c;通过 GPIO 控制了指纹模块的供电电源。但每次给整个系统板子上电时&#xff0c;BK3633 很大概率会实际而无法正常运行程序&…

修改项目的一些前端记录(自用)

<div style"background:#f2f2f2;position:absolute;top:75px;width:10%;bottom:0px">\<ol class"tree">\<li>\<label for"folder1" class"folderOne foldertop"><img src"common/img/时间.png" …

tailwindcss学习01

系列教程 01 入门 02 vue中接入 入门 # 注意使用cmd不要powershell npm init -y # 如果没有npx则安装 npm install -g npx npm install -D tailwindcss3.4.17 --registry http://registry.npm.taobao.org npx tailwindcss init修改tailwind.config.js /** type {import(tai…

【Bert】自然语言(Language Model)入门之---Bert

every blog every motto: Although the world is full of suffering&#xff0c; it is full also of the overcoming of it 0. 前言 对bert进行梳理 论文&#xff1a; BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 时间&#xff1a;…

ARM64 Trust Firmware [五]

本章介绍 ATF 中的 Runtime Service 是如何定义和被调用的。 要了解 SMC&#xff0c;必须从 SMC 指令本身开始&#xff0c;其指令如下图&#xff1a; 指令格式为&#xff1a;SMC #<imm>&#xff0c;从官方文档了解到该指令只能在 EL1 以及更高的异常等级上调用&#xff…

轻量级5G核心网:适应未来网络需求的关键方案

5G核心网 随着5G技术的迅速普及&#xff0c;网络架构正面临前所未有的变革。传统的5G核心网部署逐渐暴露出在处理大量设备连接、降低运营成本和提升网络灵活性方面的局限性。在这一背景下&#xff0c;轻量级5G核心网&#xff08;Lightweight 5G Core Network&#xff09;成为了…

uniapp uni.request重复请求处理

类似这种切换tab时&#xff0c;如果操作很快并且网络不太好&#xff0c;就出现数据错乱&#xff0c;在网上查了一圈&#xff0c;有一个使用uview拦截处理的&#xff0c;但是原生uni.requse没有找到详细的解决办法&#xff0c;就查到使用 abort 方法&#xff0c;我自己封装了一个…

一周学会Flask3 Python Web开发-http响应状态码

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 在Flask程序中&#xff0c;客户端发出的请求触发相应的视图函数&#xff0c;获取返回值会作为响应的主体&#xff0c;最后生成…

FastGPT及大模型API(Docker)私有化部署指南

​​欢迎关注【AI技术开发者】 ​ 经过优化&#xff0c;在不影响FastGPT功能的情况下&#xff0c;大幅降低了部署的设备配置要求&#xff0c;仅需1c1h即可正常部署使用。 官方要求配置&#xff1a; ​ ​ 优化后的实际占用情况&#xff1a; 运行内存仅需370M&#xff08…

个人博客5年回顾

https://huangtao01.github.io/ 五年前&#xff0c;看程序羊的b站视频做的blog&#xff0c;受限于网络&#xff0c;只能单向学习&#xff0c;没有人指导与监督&#xff0c;从来没有想过&#xff0c;有没有什么问题&#xff1f; 一、为什么要做个人博客&#xff1f; 二、我是怎么…