【iOS】SwiftUI状态管理

@State @ObservedObject @StateObject 的使用

import SwiftUIclass 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: CountModelvar 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 = falsevar 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 = falsevar 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: UserSettingsvar body: some View {VStack {Text("ThreeLevelView Hello: \(userSettings.username)")Button("Change Username in ThreeLevelView") {userSettings.username = "Three Level"}}}
}struct ParentView: View {@EnvironmentObject var userSettings: UserSettingsvar 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: Colorvar 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 中的状态管理

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跟着 Lua 5.1 官方参考文档学习 Lua (3)

文章目录 2.5 – Expressions2.5.1 – Arithmetic Operators2.5.2 – Relational Operators2.5.3 – Logical Operators2.5.4 – Concatenation2.5.5 – The Length Operator2.5.6 – Precedence2.5.7 – Table Constructors2.5.8 – Function Calls2.5.9 – Function Definiti…

(LLaMa Factory)大模型训练方法--监督微调(Qwen2-0.5B)

1、准备训练数据:SFT 的数据格式有多种,例如:Alpaca格式、OpenAI格式等。 #其中Alpaca格式如下:[{"instruction":"human instruction (required)","input":"human input (optional)",&qu…

Sojson高级加密技术科普

1. 引言 什么是Sojson? Sojson是一款用于JavaScript代码加密与混淆的工具,它能够有效保护前端代码的知识产权,避免开发者的心血被随意窃取。 为什么需要代码加密? 在当今的互联网环境下,代码被轻易复制、篡改或逆向…

自制简单的图片查看器(python)

图片格式:支持常见的图片格式(JPG、PNG、BMP、GIF)。 import os import tkinter as tk from tkinter import filedialog, messagebox from PIL import Image, ImageTkclass ImageViewer:def __init__(self, root):self.root rootself.root.…

【核心算法篇十三】《DeepSeek自监督学习:图像补全预训练方案》

引言:为什么自监督学习成为AI新宠? 在传统监督学习需要海量标注数据的困境下,自监督学习(Self-Supervised Learning)凭借无需人工标注的特性异军突起。想象一下,如果AI能像人类一样通过观察世界自我学习——这正是DeepSeek图像补全方案的技术哲学。根据,自监督学习通过…

Nginx下proxy_redirect的三种配置方式

Nginx中的proxy_redirect指令,用于修改代理服务器接收到的后端服务器响应中的重定向URL。在代理环境中,若后端返回的重定向URL不符合客户端需求,就用它调整。 语法 proxy_redirect default; proxy_redirect redirect replacement; proxy_…

使用DeepSeek+本地知识库,尝试从0到1搭建高度定制化工作流(自动化篇)

7.5. 配图生成 目的:由于小红书发布文章要求图文格式,因此在生成文案的基础上,我们还需要生成图文搭配文案进行发布。 原实现思路: 起初我打算使用deepseek的文生图模型Janus进行本地部署生成,参考博客:De…

HBuilderX中,VUE生成随机数字,vue调用随机数函数

Vue 中可以使用JavaScript的Math.random() 函数生成随机数,它会返回 0 到 1 之间的浮点数, 如果需要0到1000之前的随机数,可以对生成的随机数乘以1000,再用js的向下取整函数Math.floor() 。 let randNum Math.random(); // 生成…

Redis_基础

Redis 命令启动、配置密码 Redis是绿色软件,所以直接解压就能使用 配置文件为:redis.windows.conf 启动redis 服务: redis-server.exe redis.windows.conf启动客户端: redis-cli.exe默认没有给Redis配置密码,所以在…

网络通信基础:端口、协议和七层模型详解,网络安全零基础入门到精通实战教程!

一、端口和协议的概念 1.在网络技术中,端口(Port) 大致有两种意思: 一是物理意义上的端口,比如,ADSL Modem、集线器、交换机、路由器用于连接其他网络设备的接口,如RJ-45端口、SC端口等等。 二是逻辑意义上的端口&…

Bug:Goland debug失效详细解决步骤【合集】

Bug:Goland debug失效详细解决步骤【合集】 今天用Goland开发时,打断点,以debug方式运行,发现程序并没有断住,程序跳过了断点,直接运行结束。网上搜寻了大量文章,最后得以解决,特此在…

pycharm社区版有个window和arm64版本,到底下载哪一个?还有pycharm官网

首先pycharm官网是这一个。我是在2025年2月16日9:57进入的网站。如果网站还没有更新的话,那么就往下滑一下找到 community Edition,这个就是社区版了免费的。PyCharm:适用于数据科学和 Web 开发的 Python IDE 适用于数据科学和 Web 开发的 Python IDE&am…

WordPress Ai插件:支持提示词生成文章和chat智能对话

源码介绍 适用于 WordPress 的 AI 助手开源免费插件展开介绍,包含插件功能、使用说明、注意事项等内容,为 WordPress 用户提供了一个集成多种 AI 模型的工具选择。 插件概述:插件名称为小半 WordPress AI 助手,支持多种 AI 模型&…

Spring Boot02(数据库、Redis)---java八股

数据库相关 Mybatis的优缺点 优点: 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签&am…

【LeetCode】LCR 139. 训练计划 I

题目 教练使用整数数组 actions 记录一系列核心肌群训练项目编号。为增强训练趣味性,需要将所有奇数编号训练项目调整至偶数编号训练项目之前。请将调整后的训练项目编号以 数组 形式返回。 示例 1: 输入:actions [1,2,3,4,5] 输出&#…

波导阵列天线 学习笔记9 使用紧凑高效率馈网的宽带圆极化阵列天线

摘要: 一种宽带圆极化波导阵列天线在本文中提出。所提出的阵列天线包括四个反向对称的(antipodally)脊单元和一个有着插入阶梯腔体的两个正交膜片的紧凑型馈网。两个器件都是宽带的并且它们能独立地或者一起工作。所提出的拓扑给出了一种为大规模阵列的基础的2x2波导…

【AI战略思考15】我对做自媒体视频博主的初步探索和一些思考

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】【AI应用】 导言 因为自己找工作可能没那么快和顺利,事实是比我之前想象的要难很多,所以这几天探索了下自己能否尝试做自媒体或者视频博主来尝试赚点钱,如果做…

nodejs:express + js-mdict 网页查询英汉词典,能显示图片

向 DeepSeek R1 提问: 我想写一个Web 前端网页,后台用 nodejs js-mdict , 实现在线查询英语单词,并能显示图片 1. 项目结构 首先,创建一个项目目录,结构如下: mydict-app/ ├── public/ │ ├── …

【数据分析】2.数据分析业务全流程

业务流程方法论:3阶段6步骤 一、课程核心内容结构 1. 方法论概述 目标:系统性地解决商业中的关键问题框架:分为三个阶段,每个阶段包含两个步骤适用场景:适用于数据分析师、业务经理等需要通过数据分析支持决策的从业…

【后端】k8s

1. 命令 1.1 获取service服务 获取集群内所有命名空间的service服务 sudo kubectl get service --all-namespaces 获取集群内指定命名空间的service服务 sudo kubectl get service -n命名空间 当权限限制到一个命名空间时,只能使用下面这个 sudo kubectl -n 命名空间 get se…