• SwiftUI_2_共享绑定


    参考:

    https://blog.csdn.net/weixin_45727359/article/details/109108544

    https://zhuanlan.zhihu.com/p/141229504?from_voters_page=true

    用 @EnvironmentObject 从环境中读取值

    SwiftUI: 全局状态管理

     

    在SwiftUI中,以单一数据源(single source of truth)为核心,构建了数据驱动状态更新的机制。其中引入了多种新的属性包装器(property wrapper),用来进行状态管理。

    属性包装器(property wrapper):@State、@ObservedObject、@EnvironmentObject

    @State 用于单一视图的本地状态,

    @ObservedObject 从一个视图传递到另一个视图。

    @EnvironmentObject 比它们都更进一步:可以把一个对象注入环境,以便任何子视图都可以自动获得该对象的访问能力

      

    @State

    struct User {
        var firstName = "Bilbo"
        var lastName = "Baggins"
    }
     
    struct ContentView: View {
        @State private var user = User()  //1
     
        var body: some View {
            VStack {
                Text("Your name is \(user.firstName) \(user.lastName).")  //2
                TextField("First name", text: $user.firstName) //3
                TextField("Last name", text: $user.lastName)
            }
        }
    }  

    @State是一个属性包装器(property wrapper),被设计用来针对值类型进行状态管理;用于在Struct中mutable值类型

    • 对于 @State 修饰的属性的访问,只能发生在 body 或者 body 所调用的方法中。
    • 如果是读写都有,引用属性需要$开头,如果只读直接使用变量名即可

    @Binding

    @Binding的作用是在保存状态的属性和更改数据的视图之间创建双向连接

    将当前属性连接到存储在别处的单一数据源(single source of truth)

    struct Product:Identifiable {
        var isFavorited:Bool
        var title:String
        var id: String
    }
     
    struct FilterView: View {
        @Binding var showFavorited: Bool  //3
     
        var body: some View {
            Toggle(isOn: $showFavorited) {  //4
                Text("Change filter")
            }
        }
    }
     
    struct ProductsView: View {
        let products: [Product] = [
        Product(isFavorited: true, title: "ggggg",id: "1"),
        Product(isFavorited: false, title: "3333",id: "2")]
     
        @State private var showFavorited: Bool = false   //1
     
        var body: some View {
            List {
                FilterView(showFavorited: $showFavorited)  //2
     
                ForEach(products) { product in
                    if !self.showFavorited || product.isFavorited {
                        Text(product.title)
                    }
                }
            }
        }
    } 

    @StateObject 和 @ObservedObject 

    @StateObject 和 @ObservedObject 的区别就是实例是否被创建其的View所持有,其生命周期是否完全可控。

    @ObservedObject创建的实例生命周期可能长于/短于/等于当前的View的生命周期

    三段代码,三种结果,这也就是为什么苹果要新增@StateObject的原因——让开发者可以明确地了解并掌握实例的生命周期,消除不确定性!

    苹果使用@StateObject一方面修复了之前的隐患,同时通过SwiftUI2.0众多新特性的引入,进一步完善了Data Flow的实现手段。

    SwiftUI 2.0 —— @StateObject 研究

    class User: ObservableObject {
        @Published var firstName = "Bilbo"
        @Published var lastName = "Baggins"
    }
    
    struct ContentView: View {
        @ObservedObject private var user = User() //@ObservedObject属性包装器只能用于符合ObservableObject协议的类型
    
        var body: some View {
            VStack {
                Text("Your name is \(user.firstName) \(user.lastName).")
    
                TextField("First name", text: $user.firstName)
                TextField("Last name", text: $user.lastName)
            }
        }
    }

    @EnvironmentObject

     @EnvironmentObject 属性包装器是说明属性的数据是来自环境,而不是在本地创建的:

    class User: ObservableObject {
        @Published var name = "Taylor Swift"
    }
    
    struct EditView: View {
        @EnvironmentObject var user: User
    
        var body: some View {
            TextField("Name", text: $user.name)
        }
    }
    
    struct DisplayView: View {
        @EnvironmentObject var user: User
    
        var body: some View {
            Text(user.name)
        }
    }
    
    struct ContentView: View {
        let user = User()
    
        var body: some View {
            VStack {
                EditView().environmentObject(user)
                DisplayView().environmentObject(user)
            }
        }
    }
    

     把 ContentView 改成下面这样:你会发现结果一样。我们现在是把 user 放到 ContentView 的环境中,但是因为 EditView 和 DisplayView 都是 ContentView 的子视图,所以它们自动继承了 ContentView 的环境。

    VStack {
        EditView()
        DisplayView()
    }
    .environmentObject(user)
    

      

  • 相关阅读:
    【视频开发】【CUDA开发】英伟达CUVID硬解,并通过FFmpeg读取文件
    【视频开发】【CUDA开发】英伟达CUVID硬解,并通过FFmpeg读取文件
    【视频开发】ffmpeg 的编译选项
    【视频开发】ffmpeg 的编译选项
    【视频开发】Nvidia硬解码总结
    【视频开发】 ffmpeg支持的硬解码接口
    【视频开发】 ffmpeg支持的硬解码接口
    【视频开发】【CUDA开发】FFMPEG硬件加速-nvidia方案
    【视频开发】【CUDA开发】FFMPEG硬件加速-nvidia方案
    【视频开发】【CUDA开发】ffmpeg nvenc编码
  • 原文地址:https://www.cnblogs.com/liyonghua/p/16038410.html
Copyright © 2020-2023  润新知