• [SwiftUI 开发] @State @Binding @ObservedObject @EnvironmentObject


    @State

    @State 属性包装器, struct的属性是不可以改变的,在SwiftUI中如果想改变属性,需要加上@State。而且当 @State 装饰过的属性发生了变化,SwiftUI 会根据新的属性值重新创建视图 

    1. struct ContentView: View {
    2. @State var title = 0
    3. var body: some View {
    4. Button {
    5. title = title + 1
    6. } label: {
    7. Text("\(title)")
    8. }
    9. .font(.system(size: 38))
    10. .foregroundColor(.white)
    11. .frame(width: 88, height: 88)
    12. .background(Color.yellow)
    13. .cornerRadius(44)
    14. }
    15. }

    @Binding

    @Binding 属性修饰器, 在 Swift 中值的传递形式是值类型传递方式。但是通过 @Binding 修饰器修饰后,属性变成了一个引用类型,传递变成了引用传递,这样父子视图的状态就能关联起来了。

    1. struct ContentView: View {
    2. @State var title = 0
    3. var body: some View {
    4. UserButton(title: $title) {
    5. title = title + 1
    6. }
    7. }
    8. }
    9. struct UserButton: View {
    10. @Binding var title: Int
    11. let action: () -> Void
    12. var body: some View {
    13. Button(action: action) {
    14. Text("\(title)")
    15. .font(.system(size: 38))
    16. .foregroundColor(.white)
    17. .frame(width: 88, height: 88)
    18. .background(Color.yellow)
    19. .cornerRadius(44)
    20. }
    21. }
    22. }

    效果和上图一样

    @ObservedObject

    @Published

    @ObservedObject 和@Published 相当于KVO注册监听,@ObservedObject修饰一个对象,那就是注册了监听, @Published修饰一个对象,表示这个对象可以被监听。这俩是一对。
    想要使用@ObservedObject,必须实现ObservableObject 协议。

    1. struct ContentView: View {
    2. @ObservedObject var person: Person
    3. var body: some View {
    4. VStack{
    5. Text(person.name)
    6. Button{
    7. person.name = "韩梅梅"
    8. } label: {
    9. Text(person.name)
    10. .font(.system(size: 38))
    11. .foregroundColor(.white)
    12. .frame(width: 188, height: 88)
    13. .background(Color.yellow)
    14. .cornerRadius(10)
    15. }
    16. }
    17. }
    18. }
    19. class Person: ObservableObject {
    20. @Published var name: String = "小明"
    21. }

    @EnvironmentObject

    @EnvironmentObject 环境变量,创建对象时,通过.environmentObject(person())传值。在它所有的子界面都可以用@EnvironmentObject来接收person对象。它是通过Environment查找person对象的

    * 值得注意的是,push到另一个界面是不行的,必须要在同一个界面,因为push到的这个新View,不属于它的子View

    1. let person = Person()
    2. ContentView().environmentObject(person)
    3. struct ContentView: View {
    4. @EnvironmentObject var person: Person
    5. var body: some View {
    6. VStack{
    7. ContentView2()
    8. Button{
    9. person.name = "韩梅梅"
    10. } label: {
    11. Text(person.name)
    12. .font(.system(size: 38))
    13. .foregroundColor(.white)
    14. .frame(width: 188, height: 88)
    15. .background(Color.yellow)
    16. .cornerRadius(10)
    17. }
    18. }
    19. }
    20. }
    21. struct ContentView2: View {
    22. @EnvironmentObject var person: Person
    23. var body: some View {
    24. VStack{
    25. Button{
    26. person.name = "李雷"
    27. } label: {
    28. Text(person.name)
    29. .font(.system(size: 38))
    30. .foregroundColor(.white)
    31. .frame(width: 188, height: 88)
    32. .background(Color.yellow)
    33. .cornerRadius(10)
    34. }
    35. }
    36. }
    37. }

     @Environment

    根据@Environment我们不仅可以拿到自定义的属性,还可以拿到系统属性

    1. @Environment(\.presentationMode) var presentationMode: Binding
    2. // 比如我们需要dismiss时,就需要拿到系统presentationMode对象
    3. presentationMode.wrappedValue.dismiss()
    4. // 可以拿到系统ColorScheme对象
    5. @Environment(\.colorScheme) var colorScheme: ColorScheme

  • 相关阅读:
    RabbitMQ:主题模式
    二手车价格预测 | 构建AI模型并部署Web应用 ⛵
    TiCDC 重要监控指标详解
    Java面试整理(二)《JavaSE》
    高数基础_函数的奇偶性
    yocto meta-st-stm32mp conf文件夹分析
    类和对象之 封装 继承 与 多态
    计算机视觉常用的PR图画法
    使用pro-components遇到的问题
    springboot mybatis多数据源配置
  • 原文地址:https://blog.csdn.net/u010130947/article/details/126008932