<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>数据流与状态管理 on LYon's Blog</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/</link><description>Recent content in 数据流与状态管理 on LYon's Blog</description><generator>Hugo</generator><language>zh-cn</language><atom:link href="https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/index.xml" rel="self" type="application/rss+xml"/><item><title>objectWillChange.send() 使用场景详解</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/objectWillChange/</link><pubDate>Fri, 27 Jun 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/objectWillChange/</guid><description>&lt;p>在 SwiftUI 中，&lt;code>objectWillChange.send()&lt;/code> 是 &lt;code>ObservableObject&lt;/code> 协议的核心方法，用于通知 SwiftUI 视图模型中的数据即将发生变化。以下是详细的用法说明和实际场景：&lt;/p></description></item><item><title>观察者模式引起的无限递归问题</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%97%A0%E9%99%90%E9%80%92%E5%BD%92%E9%97%AE%E9%A2%98/</link><pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%97%A0%E9%99%90%E9%80%92%E5%BD%92%E9%97%AE%E9%A2%98/</guid><description>&lt;p>SwiftUI 的 &lt;code>@Observable&lt;/code> 宏能让数据变更自动触发 UI 更新，但在某些场景下会导致严重的无限循环问题：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-swift" data-lang="swift">&lt;span style="display:flex;">&lt;span>@Observable 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">class&lt;/span> &lt;span style="color:#f3f99d">DataManager&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">data&lt;/span>: [&lt;span style="color:#ff5c57">String&lt;/span>: &lt;span style="color:#ff5c57">Int&lt;/span>] = [:]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">func&lt;/span> &lt;span style="color:#57c7ff">calculateValue&lt;/span>(&lt;span style="color:#ff6ac1">for&lt;/span> key: &lt;span style="color:#ff5c57">String&lt;/span>) -&amp;gt; &lt;span style="color:#ff5c57">Int&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">let&lt;/span> &lt;span style="color:#ff5c57">result&lt;/span> = performCalculation()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> data[key] = result &lt;span style="color:#78787e">// 这里修改了被观察的属性&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff6ac1">return&lt;/span> result
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>当视图依赖 &lt;code>calculateValue&lt;/code> 方法时，每次视图刷新都会执行该方法，导致 &lt;code>data&lt;/code> 字典被修改，这又会触发新一轮视图刷新，形成无限循环。&lt;/p></description></item><item><title>ObservableObject</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/ObservableObject/</link><pubDate>Wed, 16 Apr 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/ObservableObject/</guid><description>&lt;p>在 SwiftUI 中，将 &lt;code>@MainActor&lt;/code> 与 &lt;code>ObservableObject&lt;/code> 结合使用是一种常见的做法，主要是为了 &lt;strong>确保线程安全&lt;/strong> 和 &lt;strong>简化 UI 更新逻辑&lt;/strong>。以下是具体原因和解释：&lt;/p>
&lt;hr>
&lt;h3 id="1-为什么">&lt;strong>1. 为什么 &lt;code>ObservableObject&lt;/code> 需要 &lt;code>@MainActor&lt;/code>？&lt;/strong>&lt;a class="anchor" href="#1-%e4%b8%ba%e4%bb%80%e4%b9%88">#&lt;/a>&lt;/h3>
&lt;h4 id="1-ui-更新必须在主线程">&lt;strong>(1) UI 更新必须在主线程&lt;/strong>&lt;a class="anchor" href="#1-ui-%e6%9b%b4%e6%96%b0%e5%bf%85%e9%a1%bb%e5%9c%a8%e4%b8%bb%e7%ba%bf%e7%a8%8b">#&lt;/a>&lt;/h4>
&lt;ul>
&lt;li>SwiftUI 的所有界面更新（如刷新 &lt;code>@Published&lt;/code> 属性绑定的视图）&lt;strong>必须发生在主线程&lt;/strong>。&lt;/li>
&lt;li>如果 &lt;code>ObservableObject&lt;/code> 的 &lt;code>@Published&lt;/code> 属性在后台线程被修改，会导致运行时警告（甚至崩溃）。&lt;/li>
&lt;/ul>
&lt;h4 id="2">&lt;strong>(2) &lt;code>ObservableObject&lt;/code> 的默认线程不安全&lt;/strong>&lt;a class="anchor" href="#2">#&lt;/a>&lt;/h4>
&lt;ul>
&lt;li>默认情况下，&lt;code>ObservableObject&lt;/code> 不限制线程，它的 &lt;code>@Published&lt;/code> 属性可能被任意线程修改。&lt;/li>
&lt;li>例如：网络请求回调、数据库操作可能在后台线程中触发属性修改。&lt;/li>
&lt;/ul>
&lt;h4 id="3-使用">&lt;strong>(3) 使用 &lt;code>@MainActor&lt;/code> 的解决方案&lt;/strong>&lt;a class="anchor" href="#3-%e4%bd%bf%e7%94%a8">#&lt;/a>&lt;/h4>
&lt;p>通过将整个 &lt;code>ObservableObject&lt;/code> 标记为 &lt;code>@MainActor&lt;/code>：&lt;/p></description></item><item><title>Observable</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Observable/</link><pubDate>Mon, 10 Mar 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Observable/</guid><description>&lt;h2 id="observable-协议和-swiftdata-的关系">Observable 协议和 SwiftData 的关系&lt;a class="anchor" href="#observable-%e5%8d%8f%e8%ae%ae%e5%92%8c-swiftdata-%e7%9a%84%e5%85%b3%e7%b3%bb">#&lt;/a>&lt;/h2>
&lt;p>在 SwiftUI 中，数据模型（Model Data）的设计和持久化与 &lt;code>Observable&lt;/code> 协议以及 &lt;code>SwiftData&lt;/code> 密切相关。以下是它们的核心关系和实现逻辑：&lt;/p>
&lt;hr>
&lt;h3 id="1-为什么需要">1. &lt;strong>为什么需要 &lt;code>Observable&lt;/code>？&lt;/strong>&lt;a class="anchor" href="#1-%e4%b8%ba%e4%bb%80%e4%b9%88%e9%9c%80%e8%a6%81">#&lt;/a>&lt;/h3>
&lt;p>&lt;code>Observable&lt;/code> 是 SwiftUI 中用于实现数据驱动 UI 更新的关键机制。它的作用包括：&lt;/p></description></item><item><title>Bindable 与 Observable</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Bindable-%E4%B8%8E-Observable/</link><pubDate>Tue, 04 Feb 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Bindable-%E4%B8%8E-Observable/</guid><description>&lt;h2 id="bindable">Bindable&lt;a class="anchor" href="#bindable">#&lt;/a>&lt;/h2>
&lt;p>在 SwiftUI 中，&lt;code>@Bindable&lt;/code> 是一个属性包装器（Property Wrapper），用于创建可绑定的状态。它通常与 &lt;code>@Observable&lt;/code> 结合使用，允许你将模型数据与视图绑定，从而实现数据的双向绑定。&lt;/p></description></item><item><title>SwiftUI 中的 @Binding 与自定义绑定</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Binding-%E8%87%AA%E5%AE%9A%E4%B9%89/</link><pubDate>Mon, 27 Jan 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Binding-%E8%87%AA%E5%AE%9A%E4%B9%89/</guid><description>&lt;p>在 SwiftUI 中，&lt;code>@Binding&lt;/code> 类型的初始化需要特别处理。以下是完整的实现方案：&lt;/p>
&lt;h3 id="1-正确初始化-binding-属性的方法">1. 正确初始化 Binding 属性的方法&lt;a class="anchor" href="#1-%e6%ad%a3%e7%a1%ae%e5%88%9d%e5%a7%8b%e5%8c%96-binding-%e5%b1%9e%e6%80%a7%e7%9a%84%e6%96%b9%e6%b3%95">#&lt;/a>&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-swift" data-lang="swift">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">import&lt;/span> &lt;span style="color:#f3f99d">SwiftUI&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#78787e">// 父视图&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">struct&lt;/span> &lt;span style="color:#f3f99d">ParentView&lt;/span>: View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> @State &lt;span style="color:#ff5c57">private&lt;/span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">text&lt;/span>: &lt;span style="color:#ff5c57">String&lt;/span> = &lt;span style="color:#5af78e">&amp;#34;初始值&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">body&lt;/span>: some View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> VStack {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Text(&lt;span style="color:#5af78e">&amp;#34;父视图的值: &lt;/span>&lt;span style="color:#5af78e">\(&lt;/span>text&lt;span style="color:#5af78e">)&lt;/span>&lt;span style="color:#5af78e">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ChildView(boundText: &lt;span style="color:#ff5c57">$&lt;/span>text) &lt;span style="color:#78787e">// 传递绑定&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#78787e">// 子视图（接受 Binding）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">struct&lt;/span> &lt;span style="color:#f3f99d">ChildView&lt;/span>: View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> @Binding &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">boundText&lt;/span>: &lt;span style="color:#ff5c57">String&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">private&lt;/span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">customText&lt;/span>: &lt;span style="color:#ff5c57">String&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#78787e">// 初始化方法&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">init&lt;/span>(boundText: Binding&amp;lt;&lt;span style="color:#ff5c57">String&lt;/span>&amp;gt;) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#78787e">// 正确初始化绑定属性（使用下划线访问属性包装器的原始值）&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff6ac1">self&lt;/span>._boundText = boundText
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#78787e">// 其他初始化逻辑&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff6ac1">self&lt;/span>.customText = &lt;span style="color:#5af78e">&amp;#34;处理后的值: &lt;/span>&lt;span style="color:#5af78e">\(&lt;/span>boundText.wrappedValue&lt;span style="color:#5af78e">)&lt;/span>&lt;span style="color:#5af78e">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">body&lt;/span>: some View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> VStack {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Text(customText)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> TextField(&lt;span style="color:#5af78e">&amp;#34;输入新值&amp;#34;&lt;/span>, text: &lt;span style="color:#ff5c57">$&lt;/span>boundText)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .padding()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .border(Color.gray)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Button(&lt;span style="color:#5af78e">&amp;#34;重置为初始值&amp;#34;&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> boundText = &lt;span style="color:#5af78e">&amp;#34;初始值&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="2-手动创建自定义-binding">2. 手动创建自定义 Binding&lt;a class="anchor" href="#2-%e6%89%8b%e5%8a%a8%e5%88%9b%e5%bb%ba%e8%87%aa%e5%ae%9a%e4%b9%89-binding">#&lt;/a>&lt;/h3>
&lt;p>如果需要创建自定义逻辑的 Binding：&lt;/p></description></item><item><title>Binding</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Binding/</link><pubDate>Wed, 22 Jan 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/Binding/</guid><description>&lt;p>在 &lt;strong>SwiftUI&lt;/strong> 中，&lt;strong>&lt;code>Binding&lt;/code>&lt;/strong> 是用来创建双向数据绑定的核心机制，允许一个视图能够读写绑定数据。这种双向绑定使得视图和数据模型（&lt;code>@State&lt;/code>、&lt;code>@EnvironmentObject&lt;/code> 等）能够保持同步。&lt;/p></description></item><item><title>PreferenceKey</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/PreferenceKey/</link><pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/PreferenceKey/</guid><description>&lt;h3 id="什么是">&lt;strong>什么是 &lt;code>PreferenceKey&lt;/code>？&lt;/strong>&lt;a class="anchor" href="#%e4%bb%80%e4%b9%88%e6%98%af">#&lt;/a>&lt;/h3>
&lt;p>&lt;code>PreferenceKey&lt;/code> 是 SwiftUI 中用于在视图树中向上传递数据的机制。 即 &lt;code>PreferenceKey&lt;/code> 提供了一种从子视图向父视图传递数据的方式。&lt;/p>
&lt;hr>
&lt;h3 id="preferencekey-的作用">&lt;strong>PreferenceKey 的作用&lt;/strong>&lt;a class="anchor" href="#preferencekey-%e7%9a%84%e4%bd%9c%e7%94%a8">#&lt;/a>&lt;/h3>
&lt;ol>
&lt;li>
&lt;p>&lt;strong>数据向上传递（向父视图传递数据）&lt;/strong>&lt;/p></description></item><item><title>onPreferenceChange</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/onPreferenceChange/</link><pubDate>Sat, 11 Jan 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/onPreferenceChange/</guid><description>&lt;h3 id="onpreferencechange">&lt;strong>&lt;code>onPreferenceChange&lt;/code> 是什么？&lt;/strong>&lt;a class="anchor" href="#onpreferencechange">#&lt;/a>&lt;/h3>
&lt;p>在 &lt;strong>SwiftUI&lt;/strong> 中，&lt;strong>&lt;code>onPreferenceChange&lt;/code>&lt;/strong> 是一个修饰符，用于监听由 &lt;code>PreferenceKey&lt;/code> 定义的值的变化。它允许在 &lt;strong>子视图树中定义一些值&lt;/strong> 并向父视图传递这些值，父视图可以通过 &lt;code>onPreferenceChange&lt;/code> 捕获这些值的变化并做出相应的调整。&lt;/p></description></item><item><title>FocusState</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/FocusState/</link><pubDate>Wed, 08 Jan 2025 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/FocusState/</guid><description>&lt;h3 id="focusstate-的介绍">&lt;strong>FocusState 的介绍&lt;/strong>&lt;a class="anchor" href="#focusstate-%e7%9a%84%e4%bb%8b%e7%bb%8d">#&lt;/a>&lt;/h3>
&lt;p>&lt;code>FocusState&lt;/code> 是 SwiftUI 中用于管理 &lt;strong>键盘焦点状态&lt;/strong> 的工具，始于 &lt;strong>iOS 15+&lt;/strong> 和 &lt;strong>macOS 12+&lt;/strong>。它专门用于在多输入框场景中控制某个输入组件（如 &lt;code>TextField&lt;/code> 或 &lt;code>SecureField&lt;/code>）的焦点状态，或者在程序中让特定的输入字段成为焦点。&lt;/p></description></item><item><title>ObservedObject</title><link>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/SwiftUI-Model-Data/</link><pubDate>Sun, 27 Oct 2024 00:00:00 +0000</pubDate><guid>https://yindongliang.com/docs/Apple/SwiftUI/%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%8E%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86/SwiftUI-Model-Data/</guid><description>&lt;h2 id="1-state-和-binding">1. &lt;code>@State&lt;/code> 和 &lt;code>@Binding&lt;/code>&lt;a class="anchor" href="#1-state-%e5%92%8c-binding">#&lt;/a>&lt;/h2>
&lt;p>&lt;a href="https://developer.apple.com/documentation/swiftui/state">https://developer.apple.com/documentation/swiftui/state&lt;/a>&lt;/p>
&lt;p>&lt;code>@State&lt;/code> 是 SwiftUI 中用于声明本地状态变量的属性包装器。任何使用到 &lt;code>@State&lt;/code> 变量的视图，当该变量变化时，都会重新渲染。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#e2e4e5;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-swift" data-lang="swift">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">import&lt;/span> &lt;span style="color:#f3f99d">SwiftUI&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ff5c57">struct&lt;/span> &lt;span style="color:#f3f99d">ContentView&lt;/span>: View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> @State &lt;span style="color:#ff5c57">private&lt;/span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">counter&lt;/span> = &lt;span style="color:#ff9f43">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ff5c57">var&lt;/span> &lt;span style="color:#ff5c57">body&lt;/span>: some View {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> VStack {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Text(&lt;span style="color:#5af78e">&amp;#34;Counter: &lt;/span>&lt;span style="color:#5af78e">\(&lt;/span>counter&lt;span style="color:#5af78e">)&lt;/span>&lt;span style="color:#5af78e">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Button(action: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> counter &lt;span style="color:#ff6ac1">+=&lt;/span> &lt;span style="color:#ff9f43">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Text(&lt;span style="color:#5af78e">&amp;#34;Increment Counter&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>@Binding&lt;/code> 用于在不同视图之间传递和共享 &lt;code>@State&lt;/code> 数据，使得一个视图可以绑定到另一个视图的状态。&lt;/p></description></item></channel></rss>