SwiftUI教程使用@State
关键字来表示可变的 UI 状态:
@State var showFavoritesOnly = false
它提供了以下摘要:
状态是一个值或一组值,可以随时间变化,并影响视图的行为、内容或布局。您可以使用带有 @State 属性的属性来向视图添加状态。
- 关键字究竟是什么意思?
- 变异变量如何
@State
导致重新计算视图? body
getter中的其他变量如何不可变?
@State
关键字是 a ,这@propertyWrapper
是最近在 Swift 5.1 中引入的一个特性。正如相应提案中所解释的,它是一种避免样板代码的值包装器。
旁注:@propertyWrapper
以前被称为@propertyDelegate
,但此后发生了变化。有关更多信息,请参阅此帖子。
@State官方文档有以下内容:
SwiftUI
管理您声明为状态的任何属性的存储。 当状态值改变时,视图使其外观无效并重新计算 body。使用状态作为给定视图的唯一真实来源。State 实例不是值本身;这是一种读取和改变 value 的方法。要访问一个状态的基础值,请使用它的 value 属性。
因此,当您初始化一个标记为 的属性时@State
,您实际上并没有创建自己的变量,而是提示在后台SwiftUI
创建“某物”来存储您设置的内容并从现在开始对其进行监控!你@State var
只是作为一个代表来访问这个 wrapper。
每次写入@State
变量时,都会知道它正在监视它。它还将知道变量是否是从's读取的。使用此信息,它将能够在更改此变量后重新计算任何已在其中引用的变量。SwiftUI
@State
View
body
View
@State
body
WWDC 视频中的示例很好地解释了它- Session 204(从 16:00 开始,报价从 20:15 开始)
变量的特殊属性之一
@State
是 SwiftUI 可以观察它们何时被读取和写入。因为 SwiftUI 知道它zoomed
被读入body
,所以它知道视图的渲染依赖于它。这意味着 - 当变量更改时,框架将body
再次要求使用新@State
值。
作为@State
属性包装器也在Data Flow Through Swift UI (5:38) WWDC 视频中进行了详细说明和证明。struct
它展示了当我们需要不可变 ( )中的可变值时它如何解决问题View
。
如果你知道 React Native,让我补充一点。
该属性与 React Native 中@State
的对象非常相似。this.state
例如:
struct Foobar: some View {
@State var username = ""
}
class Foobar extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
};
}
}
当您修改用户名变量时,它们将具有相同的效果,即重新呈现当前页面。
如果你点击进去@State
,你可以看到它有几个 getter。一个与Value
另一个与Binding<Value>
。SwiftUI 似乎严重依赖响应式编程(及其新Combine
框架,并且由于我们看不到这些包装器的完整实现,我希望通过@State
属性包装器存储的值由CurrentValueSubject
from管理Combine
。顾名思义,这实质上存储了当前值,然后可以通过使用$
语法将其用作可绑定属性。
我喜欢斯坦福大学的 Paul Hegarty 教授的解释。他说@State 基本上将该变量转换为指向内存中其他地方的某个布尔值的指针,这就是值发生变化的地方。但是你的变量——现在是一个带有@State 的指针——没有改变,总是指向内存中的那个地方。
注意:- 接受的答案是正确的,但如果您试图寻找我在下面尝试的更简单的解释
@State属性包装器允许我们更改结构内的值。
注意:- 您不能将结构中的属性更改为它的值类型,因此不允许。
struct ExampleTextView: View {
// Declare a variable with state property wrapper
@State private var shouldChangeText: Bool = false
var body: some View {
Text("Just an example")
.foregroundColor(Color.white)
}
}
如果您想知道我们是否应该添加私有访问说明符?
是的,根据经验,苹果建议 @State 属性不应与其他视图共享,因为该 @ObservedObject 和 @EnvironmentObject 有更具体的属性包装器。
但是,如果它是值类型,那么它如何被变异它存储在哪里呢?
因此,每当我们使用 @State 标记属性时,我们会将其存储从结构移出到由 SwiftUI 管理的共享存储中。
如果您想与 Swift 进行比较,这就是它在那里完成的方式,
struct Example {
var exampleType: String
mutating func changeType() {
exampleType = "Are we allowed to do this?"
}
}
信用:请注意,这个答案的灵感来自这篇文章https://www.hackingwithswift.com/quick-start/swiftui/what-is-the-state-property-wrapper
如果您了解 C# 和 windows 开发。@State
如果与x:Bind
或不同Binding
,则相似。在集合中,如果与 不同,则相似ObservableCollection
。
正如 fredpi 所说,SwiftUI 正在列出带有@State
属性委托的 vars 更新。