美文网首页
swiftUI中的属性装饰器

swiftUI中的属性装饰器

作者: Mjs | 来源:发表于2023-04-22 15:25 被阅读0次

    @State
    使用@State修饰某个属性后,SwiftUI将会把该属性存储到一个特殊的内存区域内,并且这个区域和View struct是隔离的;
    当@State修饰的属性的值发生变化后,SwiftUI会根据该属性重新绘制视图;

    struct ContentView: View {
        @State private var str: String = ""
        var body: some View {
            VStack {
                TextField("Placeholder", text: $str)
                Text("\(str)")
            }
        }
    }
    

    @Binding
    开发中,我们需要把一个View的属性,传递到一个子View中;
    Swift中,值传递的形式是值传递,也就是说,传个子View的是值的拷贝;子视图对这个值进行了修改后,不会影响父视图;
    使用@Binding修饰后,属性就变成了一个引用类型,这样子视图对值进行了修改后,父视图中的值也会发生变化

    // 父视图
    struct BindViewTest: View {
        
        @State var count = 0
        
        var body: some View {
            VStack(alignment: .center) {
                Text("\(count)").padding()
                BindSubView(count: $count).padding()
            }
            .padding()
        }
    }
    
    // 子视图
    struct BindSubView: View {
        
        @Binding var count: Int
        
        var body: some View {
            Button(action: {
                count += 1
            }) {
                Text("增加")
            }
        }
    }
    

    struct class区别
    struct 是值类型的valueType、 值类型的变量包含数据,会进行值的copy,存储在Stack栈中,struct速度更快
    class是引用类型的ReferenceType,引用类型的变量,存储对他们数据的引用,存储在heap堆中

    使用@Binding标记子画面中的content属性,并且在构造SubView时,使用$符号将String类型转换为Binding<String>类型,此时,SubView持有的是主View的content的投影属性,无论我们通过点击ContentView还是通过点击SubView来修改content的值,两个View均会同步更新。

    @ObservableObject
    对实例进行监听,其用处和@State非常相似,只不过必须是对象,而且这个被监听的对象可以被多个视图使用。需要注意用法

    class DelayedUpdater: ObservableObject {
        @Published var value = 0
        init() {
            for i in 1...10 {
                DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
                    self.value += 1
                }
            }
        }
    }
    
    struct ContentView: View {
        @ObservedObject var updater = DelayedUpdater()
        var body: some View {
            VStack {
                Text("\(updater.value)").padding()
            }
        }
    }
    

    说明:

    1. 绑定的数据是一个对象。
    2. 被修饰的对象,其类必须遵守ObservableObject协议
    3. 此时这个类中被@Published修饰的属性都会被绑定
    4. 使用@ObservedObject修饰这个对象,绑定这个对象。
    5. 被@Published修饰的属性发生改变时,SwiftUI就会进行更新。
    6. 这里当value值会随着时间发生改变。所以updater对象也会发生改变。此时文本视图的内容就会不断更新。

    @EnvironmentObject
    在多视图中,为了避免数据的无效传递,可以直接将数据放到环境中,供多个视图进行使用。

    struct EnvView: View {
        @EnvironmentObject var updater: DelayedUpdater
        
        var body: some View {
            Text("\(updater.value)")
        }
    }
    
    struct BtnvView: View {
        @EnvironmentObject var updater: DelayedUpdater
        
        var body: some View {
            Text("\(updater.value)")
        }
    }
    struct ContentView: View {
        let updater = DelayedUpdater()
        var body: some View {
            VStack {
                //EnvView().environmentObject(updater)
                //BtnvView().environmentObject(updater)
                EnvView()
                BtnvView()
            }.environmentObject(updater)
        }
    }
    

    说明:

    • 给属性添加@EnvironmentObject修改,就将其放到了环境中。
    • 其他视图中想要获取该属性,可以通过.environmentObject从环境中获取。
    • 可以看到分别将EnvView和BtnvView的属性分别放到了环境中之后我们ContentView视图中获取数据时,可以直接通过环境获取。
    • 不需要将数据传递到ContentView,而是直接通过环境获取,这样避免了无效的数据传递,更加高效
    • 如果是在多层级视图之间进行传递,会有更明显的效果。

    AppStorage
    AppStorage是一个全局的存储,它是使用UserDefaults来做持久化的,所以我们可以在app中任何地方获取使用它。它也是用于轻量级存储,例如app的设置信息。

    
    struct AppStorageDemo: View {
    //    @AppStorage userDefaults 全局的
        @AppStorage("message") var message:String = ""//userDefaults
        var body: some View {
            VStack{
                Text("本地存储数据:\n\(message)")
                TextField("请输入要存储的信息", text: $message).padding(10).border(.orange,width: 2)
                Button("按钮存储") {
                    message = "按钮存储信息"
                }.font(.title)
            }.padding()
        }
    }
    
    

    @SceneStorage swiftUI接管的 只能用在View上

    相关文章

      网友评论

          本文标题:swiftUI中的属性装饰器

          本文链接:https://www.haomeiwen.com/subject/hemsjdtx.html