SwiftUI @State 与绑定

Arc*_*nes 17 ios swiftui

我正在使用 Swift 和 SwiftUI 学习 iOS 编程。我知道的很少,我对 a@State和 a之间的区别感到非常困惑Binding<*>

如果我理解正确,Binding这只是技术上的,State但它不会更新视图。如果是这样的话,Binding如果我可以State用来做同样的事情,我为什么需要?

ARG*_*Geo 33

关于@State和@Binding

\n

想象一下您有两个 SwiftUI 视图的情况。在第一个视图中,您声明了一个count属性,在第二个视图中,您创建了一个Tap Me按钮。当点击按钮时,count第一个视图中的值应该更新。要实现此逻辑,您需要@State第一个视图中的属性包装器和@Binding第二个视图中的属性包装器。

\n

@State允许在本地操作少量数据value type@State直接创建和管理值,因此它是Source of Truth. @Binding也指value type不同视图所拥有的数据。@Binding不是真理的来源。为了提供@State属性,Binding<T>您需要使用$运算符(即它看起来像$count)。@Binding在属性和另一个视图之间创建双向连接。

\n

这是代码:

\n

在此输入图像描述

\n
import SwiftUI\n\nstruct FirstView: View {\n    \n    @State private var count: Int = 0\n    \n    var body: some View {\n        ZStack {\n            Color.black.ignoresSafeArea()\n            VStack {\n                SecondView(counter: $count).frame(width: 300, height: 100)\n                Text("Tapped \\(count) times").foregroundStyle(.white)\n            }\n        }\n    }\n}\n                        \nstruct SecondView: View {\n    \n    @Binding var counter: Int\n    \n    var body: some View {\n        ZStack {\n            Color.yellow\n            Text("Tap Me").onTapGesture { counter += 1 }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

除了上述属性包装器之外,借助所谓的“trinity”-kit \xe2\x80\x93 和 也可以实现类似@StateObject@Published结果@ObservedObject

\n

属性包装器

\n

下面的数据透视表代表了 20 个常用的 SwiftUI 属性包装器的三个主要特征(事实来源、目的和语义)。

\n
\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n
#属性包装器真理之源这是做什么用的?语义学
01@应用存储是的从 UserDefaults 读取/写入价值
02@捆绑创建双向连接价值
03@环境从系统读取数据价值
04@EnvironmentObject从多个视图读取共享对象参考
05@FetchRequest是的将其用于 CoreData 获取请求价值
06@FocusedBinding从聚焦视图观察和展开状态绑定价值
07@FocusedValue@FocusedBinding 的简单版本价值
08@GestureState是的存储活动手势的值价值
09@命名空间是的是namespace.id的包装器,可以防止名称冲突价值
10@ObservedObject引用符合 ObservableObject 的外部类的实例参考
11@已发布是的附加到 ObservableObject 内部的属性价值
12@ScaledMetric是的允许应用程序视图缩放给定用户的动态类型设置价值
13@场景存储是的恢复系统状态的轻量级数据价值
14@状态是的在本地操作视图的数据价值
15@StateObject是的存储符合 ObservableObject 的新实例参考
16@NSApplicationDelegateAdaptor是的创建一个 AppKit 应用委托协议
17 号@UIApplicationDelegateAdaptor是的创建一个 UIKit 应用程序委托协议
18@Observable这是宏观的iOS 17 替代 ObservableObject + @Published + @ObservedObject 模式参考
19@询问这是宏观的读取 SwiftData 管理的 Destination 对象参考
20@模型这是宏观的从 SwiftData 加载和存储一个类参考
\n

如何...

\n

以下是如何使用四种流行的属性包装器的示例。

\n\n


Raj*_*rma 28

SwiftUI 是一个声明式的面向组件的框架。你必须忘记 MVC,在那里你有控制器在视图和模型之间进行调解。SwiftUI 使用差异算法来理解更改并仅更新相应的视图。

@状态

  • State 属性连接到视图。视图永久读取 State 属性。这意味着每次@State 属性更改/更新时,视图都会重新渲染并最终根据@State 的数据显示内容。
  • 只有特定视图才能访问状态。
  • 字符串、整数和布尔值等简单属性属于单个视图 - 标记为私有。
  • 所有标记为State的字段都存储在特殊的分离内存中,只有对应的视图才能访问和更新它们。

@捆绑

  • BindableObject 协议,需要 didChange 属性。它可以在环境中使用它并在它发生变化时立即重建视图。
  • didChange 属性应该是一个 Publisher,它是一个名为 Combine 的新 Apple 响应式框架的一部分。
  • Publisher 的主要目标是在发生变化时通知所有订阅者。一旦出现新值,SwiftUI 将重建视图。

@环境对象

  • 它是称为环境的功能的一部分。您可以使用所有需要的服务类填充您的环境,然后从该环境内的任何视图访问它们。
  • @EnvironmentObject 可用于环境中的每个视图。
  • @EnvironmentObject 在其他地方创建的属性,例如共享数据。如果丢失,应用程序会崩溃。
  • 环境是使用 SwiftUI 进行依赖注入的正确方式。


小智 27

两者@State@Binding为物业包装。

@状态

  • 它用于每次更新变量的值。
  • 我们也可以说这是一种双向绑定。
  • 如果我们更改属性状态,那么 SwiftUI 将自动重新加载视图的主体。
  • 它用于简单的属性,如字符串、整数和布尔值。

@捆绑

  • 使用它,您可以访问另一个视图的状态属性。
  • 它将为您提供对变量的读写访问权限。


All*_*ian 15

将其State视为您观点的唯一真实来源,作为改变变量并使观点无效以反映该状态的一种手段。

Binding另一方面,是视图与其底层模型之间的双向连接。改变State不受视图管理的 a 的方法(例如Toggle,反映并控制控件本身不知道其存储或来源的布尔值的 a )

最后,您可以使用前缀运算符Binding从 any 中获取 a 。State$

在它们之间进行选择的简单指南是:

我是否需要修改一个我私有的值?=> 状态

我是否需要修改某个其他视图的状态?=> 绑定


bau*_*sic 10

我想提供一个非常简短的“实际用途”解释,这帮助我弄清楚了。我没有定义状态/绑定,我只是指出其中的巨大差异。

@State具有价值,即“真理之源”

@Binding传递值,用作管道。

关于@State 的一件重要事情:更改将触发重绘。更改@State的值将导致整个视图“重新执行”。


Pra*_*Das 5

状态

•   @State keyword allows us to ask the SwiftUI to monitor the value of the property. Once the value will change, the View will be invalidated and rendered again in efficient manner.
•   A persistent value of a given type, through which a view reads and monitors the value.
•   It is just another @propertyWrapper that outlines a source of truth.
•   When you use state the framework allocate persistence storage for variable and tracks it as a dependency ... you alway has to specify an initial constant value"
Run Code Online (Sandbox Code Playgroud)

捆绑

•   @Binding and $ prefix allows passing State property into the nested child.
•   A manager for a value that provides a way to mutate it.
•   @Binding yet another @propertyWrapper that depends explicitly on state.
•   By using the Binding property wrapper you define an explicit dependency to a source of truth without owning it, additionally you don't need to specify an initial value because binding can be derived from state.
Run Code Online (Sandbox Code Playgroud)

链接供您参考:https : //medium.com/stepstone-tech/swiftui-101-how-to-use-state-and-binding-in-your-first-custom-ui-control-64d395947492