【iOS】SwiftUI状态管理

news2025/4/8 23:46:15

@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 中的状态管理

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

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

相关文章

自制简单的图片查看器(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.…

ChatGPT行业热门应用提示词案例-AI绘画类

AI 绘画指令是一段用于指导 AI 绘画工具(如 DALLE、Midjourney 等)生成特定图像的文本描述。它通常包含场景、主体、风格、色彩、氛围等关键信息,帮助 AI 理解创作者的意图,从而生成符合要求的绘画作品。 ChatGPT 拥有海量的知识…

Visual Studio Code的下载安装与汉化

1.下载安装 Visual Studio Code的下载安装十分简单,在本电脑的应用商店直接下载安装----注意这是社区版-----一般社区版就足够用了---另外注意更改安装地址 2.下载插件 重启后就是中文版本了

分词器(Tokenizer) | 有了分词器,为什么还需要嵌入模型

文章目录 什么是tokenizer有了分词器,为什么还需要嵌入模型分词器为什么在transformers 里Hugging Face的Tokenizer大模型不同tokenizer训练效果对比分词器库选择当前顶尖大模型所采用的 Tokenizer 方法与词典大小 参考 什么是tokenizer Tokenizers huggingface官方…

scala中 隐式转换

一、 隐式转换: 编译器 偷偷地,自动地帮我们把一种数据类型转换为另一种类型 例如: int --> double object test {// 复习隐式转换// 隐式转换: 编译器 偷偷地,自动地帮我们把一种数据类型转换为另一…

实战开发coze应用-姓氏头像生成器(上)

​欢迎关注【AI技术开发者】 上次,我们开发了一个对话形式的头像生成器智能体(Agents),广受大家欢迎。 同时也接收到一些用户的反馈,生成前无法看到头像样式、初次使用不会用等等。 对此,我准备使用Coze开…

【Node.js】express框架

目录 1初识express框架 2 初步使用 2.1 安装 2.2 创建基本的Web服务器 2.3 监听方法 2.3.1 监听get请求 2.3.2 监听post请求 2.4 响应客户端 2.5 获取url中的参数(get) 2.5.1 获取查询参数 2.5.2 获取动态参数 2.6 托管静态资源 2.6.1 挂载路径前缀 2.6.2 托管多…

JS逆向实战三:1688工厂信息

本文说明:B站学习笔记整理,仅供学习参考~~ 网站:https://sale.1688.com/factory/category.html 1. 页面分析与解密 刷新页面,通过对关键词进行搜索,实现接口定位。 通过多次刷新页面或者页面翻页,找到变化…

Pipeline 获取 Jenkins参数

Pipeline 获取 Jenkins参数 Jenkins 提供了一系列默认的环境变量,这些变量在构建过程中可以被使用。以下是一些常见的 Jenkins 默认环境变量: WORKSPACE: 当前构建的工作目录路径 JOB_NAME: 当前构建的作业名称 BUILD_NUMBER: 当前构建的编号&#xff…

ESP32 在IDF_V5.3.1版本下实现AP无线热点模式!(带WIFI事件处理)

一、什么是ESP32的AP无线热点模式? ESP32 的 AP(Access Point)模式 是指 ESP32 作为无线接入点运行,它自己创建一个 Wi-Fi 网络,允许其他设备(如手机、电脑、平板等)直接连接到它上面&#xff0…

Elasticsearch:探索 CLIP 替代方案

作者:来自 Elastic Jeffrey Rengifo 及 Toms Mura 分析图像到图像和文本到图像搜索的 CLIP 模型的替代方案。 在本文中,我们将通过一个模拟房地产网站的实际示例介绍 CLIP 多模态模型,探索替代方案,并分析它们的优缺点&#xff0c…

Nginx 在Linux中安装、使用

Nginx 在Linux中安装、使用 一、官网下载Nginx 官网地址:http://nginx.org/en/download.html 二、上传到服务器解压 1、上传到指定的服务器地址 上传的地址自己决定,我上传到 /data/home/prod/nginx/ 2、解压 使用命令: tar -zxvf “你的N…

【Spring+MyBatis】_图书管理系统(下篇)

图书管理系统上篇、中篇如下: 【SpringMyBatis】_图书管理系统(上篇)-CSDN博客 【SpringMyBatis】_图书管理系统(中篇)-CSDN博客 目录 功能5:删除图书 6.1 约定前后端交互接口 6.2 后端接口 6.3 前端…

若依-@Excel新增注解numberFormat

Excel注解中原本的scale会四舍五入小数,导致进度丢失 想要的效果 显示的时候保留两个小数真正的数值是保留之前的数值 还原过程 若以中有一個專門的工具类,用来处理excel的 找到EXCEL导出方法exportExcel()找到writeSheet,写表格的方法找到填充数据的方法…

Cherry-Studio下载安装教程,AI面向开发者的工具或平台(付安装包)

文章目录 一、Cherry Studio是什么?二、功能特点 一、Cherry Studio是什么? Cherry Studio 是一款开源跨平台的多模型服务桌面客户端,集成超 300 个大语言模型,内置 300 多个预配置 AI 助手,支持多格式文件处理、全局…

多信道接收机

线性调频(LFM)信号,模拟多个目标反射的回波信号,并进行混频和滤波处理。 % 参数设置 c 3e8; % 光速 (m/s) f0 8.566e9; % 载波频率 (Hz) T 10e-6; % 脉冲持续时间 (s) B 100e6; % 信号带宽 (Hz) mu B / T; % 调频斜率 (Hz/s…

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

<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" …

阿里云虚机的远程桌面登录提示帐户被锁定了

提示由于安全原因&#xff0c;帐户被锁定。 阿里云虚机ECS的远程桌面登录提示帐户被锁定了&#xff0c;只能登录阿里云处理 阿里云-计算&#xff0c;为了无法计算的价值 需选择通过VNC连接 然后计算机管理&#xff0c;解除帐户锁定即可。

AD(Altium Designer)器件封装——立创商城导出原理图和PCB完成器件封装操作指南

1、立创商城下载原理图和PCB图 1.1 打开立创商城 官网:www.SZLCSC.COM 1.2 寻找所需器件 以芯片为例 器件类——>芯片类——>对应芯片 1.3 确定所需芯片 确定芯片——>数据手册 1.4 打开原理图和PCB图 1:原理图 2:PCB 3:打开 1.5 导出原理图 操作

【DeepSeek系列】04 DeepSeek-R1:带有冷启动的强化学习

文章目录 1、简介2、主要改进点3、两个重要观点4、四阶段后训练详细步骤4.1 冷启动4.2 推理导向的强化学习4.3 拒绝采样和有监督微调4.4 针对所有场景的强化学习 5、蒸馏与强化学习对比6、评估6.1 DeepSeek-R1 评估6.2 蒸馏模型评估 7、结论8、局限性与未来方向 1、简介 DeepS…