@State 属性包装器, struct的属性是不可以改变的,在SwiftUI中如果想改变属性,需要加上@State。而且当 @State 装饰过的属性发生了变化,SwiftUI 会根据新的属性值重新创建视图
- struct ContentView: View {
- @State var title = 0
- var body: some View {
- Button {
- title = title + 1
- } label: {
- Text("\(title)")
- }
- .font(.system(size: 38))
- .foregroundColor(.white)
- .frame(width: 88, height: 88)
- .background(Color.yellow)
- .cornerRadius(44)
- }
- }

@Binding 属性修饰器, 在 Swift 中值的传递形式是值类型传递方式。但是通过 @Binding 修饰器修饰后,属性变成了一个引用类型,传递变成了引用传递,这样父子视图的状态就能关联起来了。
- struct ContentView: View {
- @State var title = 0
- var body: some View {
- UserButton(title: $title) {
- title = title + 1
- }
- }
- }
-
-
- struct UserButton: View {
-
- @Binding var title: Int
- let action: () -> Void
-
- var body: some View {
- Button(action: action) {
- Text("\(title)")
- .font(.system(size: 38))
- .foregroundColor(.white)
- .frame(width: 88, height: 88)
- .background(Color.yellow)
- .cornerRadius(44)
- }
- }
- }
效果和上图一样
@ObservedObject 和@Published 相当于KVO注册监听,@ObservedObject修饰一个对象,那就是注册了监听, @Published修饰一个对象,表示这个对象可以被监听。这俩是一对。
想要使用@ObservedObject,必须实现ObservableObject 协议。
- struct ContentView: View {
-
- @ObservedObject var person: Person
-
- var body: some View {
- VStack{
- Text(person.name)
-
- Button{
- person.name = "韩梅梅"
- } label: {
- Text(person.name)
- .font(.system(size: 38))
- .foregroundColor(.white)
- .frame(width: 188, height: 88)
- .background(Color.yellow)
- .cornerRadius(10)
- }
- }
- }
- }
-
-
- class Person: ObservableObject {
- @Published var name: String = "小明"
- }

@EnvironmentObject 环境变量,创建对象时,通过.environmentObject(person())传值。在它所有的子界面都可以用@EnvironmentObject来接收person对象。它是通过Environment查找person对象的
* 值得注意的是,push到另一个界面是不行的,必须要在同一个界面,因为push到的这个新View,不属于它的子View
- let person = Person()
- ContentView().environmentObject(person)
-
- struct ContentView: View {
- @EnvironmentObject var person: Person
- var body: some View {
- VStack{
- ContentView2()
-
- Button{
- person.name = "韩梅梅"
- } label: {
- Text(person.name)
- .font(.system(size: 38))
- .foregroundColor(.white)
- .frame(width: 188, height: 88)
- .background(Color.yellow)
- .cornerRadius(10)
- }
- }
- }
- }
-
-
- struct ContentView2: View {
- @EnvironmentObject var person: Person
- var body: some View {
- VStack{
- Button{
- person.name = "李雷"
- } label: {
- Text(person.name)
- .font(.system(size: 38))
- .foregroundColor(.white)
- .frame(width: 188, height: 88)
- .background(Color.yellow)
- .cornerRadius(10)
- }
- }
- }
- }

根据@Environment我们不仅可以拿到自定义的属性,还可以拿到系统属性
- @Environment(\.presentationMode) var presentationMode: Binding
-
- // 比如我们需要dismiss时,就需要拿到系统presentationMode对象
- presentationMode.wrappedValue.dismiss()
-
-
- // 可以拿到系统ColorScheme对象
- @Environment(\.colorScheme) var colorScheme: ColorScheme