SwiftUI 中,视图的状况管理分为两种:一种是只读的数据,称之为 Swift 的特点(Property);一种则是可读可写的,需求运用 State 进行数据绑定。子视图的状况管理都存在最近的公共先人视图上,如下图:

SwiftUI 入门教程 - 用户交互状态管理

当运用 State 进行绑定之后,当数据源产生改动的时分,SwiftUI 会主动去更新需求改动的视图。

运用 Swift 的特点来存储不变的数据

运用特点来存储一些不变的数据,比如视频的标题:

struct ContentView: View {
    let videoTitle = "视频标题"
    var body: some View {
        Text(videoTitle)
    }
}

首要,声明一个 videoTitle 特点来存储视频标题,然后在 Text 中展示标题内容。

State 的运用

当视图的某个数据需求改动时,运用 State 的特点包裹器声明即可。比如播映按钮,需求根据播映的状况来改动按钮的图标。咱们能够声明一个 isPlaying 的特点来标明是否正在播映:

struct ContentView: View {
    @State private var isPlaying = false
    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }) {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        }
    }
}

首要,咱们声明一个用 @State 润饰的布尔类型的特点 isPlaying。接着,在 body 中返回一个 Button。Button 的 action 则是调用一个 toggle() 函数。它的作用是将 true 变为 false,或者将 false 变为 true。最终,则是根据 isPlaying 的值来决议按钮的图标是播映还是暂定。

当咱们将 isPlaying 用 State 包裹时,就相当于告诉 SwiftUI 它需求管理底层存储的数据。 Button 经过 state 的 wrappedValue 特点去读写存储的数据。当你修改了 isPlaying 的值,SwiftUI 则会去更新 Image 视图。

关于 wrappedValue:经过底层代码能够看到,State 是一个结构体。而 wrappedValue 则是它的一个特点,从名字也能够看出是用来存储底层的数据。通常,开发者不需求显式的去调用它,直接拜访 State 包裹的特点即可正常的拜访底层存储的数据。

需求注意的是,声明 State 特点的时分,应该加上 private 润饰符,这样能够确保特点的生命周期与相应的视图生命周期保持一致。所以,关于持久化存储的数据不要运用 State,由于这样会导致数据的生命周期长过视图的生命周期。State 应该用于保存视图的用户交互相关的数据,比如按钮的高亮状况,过滤设置等。

经过 Bind 共享数据

假如咱们想让子视图也能够拜访 State 存储的数据,能够经过 @Bind 来实现。比如下面的代码:

// 播映按钮
struct PlayButton: View {
    @Binding var isPlaying: Bool
    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }) {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        }
    }
}
// 播映视图
struct PlayerView: View {
    @State private var isPlaying: Bool = false
    var body: some View {
        PlayButton(isPlaying: $isPlaying)
    }
}

PlayButton_Previews 假如默认代码会报错,在里面声明一个 State 特点即可:

struct PlayButton_Previews: PreviewProvider {
    @State static var value = false
    static var previews: some View {
        PlayButton(isPlaying: $value)
    }
}

$ 前缀会去读取 projectedValue 的值,它是 Bind 底层存储数据的特点。