美文网首页
SwiftUi的属性装饰器

SwiftUi的属性装饰器

作者: Keyon_9468 | 来源:发表于2019-11-14 16:21 被阅读0次

    @Status
    通过使用 @State 修饰器我们可以关联出 View 的状态. SwiftUI 将会把使用过 @State 修饰器的属性存储到一个特殊的内存区域,并且这个区域和 View struct 是隔离的. 当 @State 装饰过的属性发生了变化,SwiftUI 会根据新的属性值重新创建视图

    struct ContentView: View {
        @State var score = 0
    
        var body: some View {
            VStack {
                Text("Your score is \(score)")
                Button(action: {
                    self.score += 1
                }) {
                    Text("Increase Score")
                }
            }
        }
    }
    

    @Binding

    有时候我们会把一个视图的属性传至子节点中,但是又不能直接的传递给子节点,因为在 Swift 中值的传递形式是值类型传递方式,也就是传递给子节点的是一个拷贝过的值。但是通过 @Binding 修饰器修饰后,属性变成了一个引用类型,传递变成了引用传递,这样父子视图的状态就能关联起来了。

    struct ContentView: View {
        @State var score = 0
        @State var isShowActivity = false
        var body: some View {
            VStack {
                Text("Your score is \(score)")
                Button(action: {
                    self.score += 1
                }) {
                    Text("Increase Score")
                }
                TestView(isShowActivity: $isShowActivity)
                if isShowActivity {
                    Text("TestView")
                }
            }
        }
    }
    
    struct TestView: View {
        @Binding var isShowActivity:Bool
        
        var body: some View {
            HStack {
                Toggle(isOn: $isShowActivity) {
                    Text("Change isShowActivity")
                }
            }
        }
    }
    

    @ObservedObject

    @ObservedObject 的用处和 @State 非常相似,从名字看来它是来修饰一个对象的,这个对象可以给多个独立的 View 使用。如果你用 @ObservedObject 来修饰一个对象,那么那个对象必须要实现 ObservableObject 协议,然后用 @Published 修饰对象里属性,表示这个属性是需要被 SwiftUI 监听的

    struct ContentView: View {
        @ObservedObject var settings = UserSettings()
        
        @State var isShowActivity = false
        var body: some View {
            VStack {
                Text("Your score is \(settings.score)")
                Button(action: {
                    self.settings.score += 1
                }) {
                    Text("Increase Score")
                }
                TestView(isShowActivity: $isShowActivity)
                if isShowActivity {
                    Text("TestView")
                }
            }
        }
    }
    
    struct TestView: View {
        @Binding var isShowActivity:Bool
        
        var body: some View {
            HStack {
                Toggle(isOn: $isShowActivity) {
                    Text("Change isShowActivity")
                }
            }
        }
    }
    
    class UserSettings: ObservableObject {
        @Published var score = 0
    }
    

    @EnvironmentObject
    从名字上可以看出,这个修饰器是针对全局环境的。通过它,我们可以避免在初始 View 时创建 ObservableObject, 而是从环境中获取 ObservableObject

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
        var window: UIWindow?
    
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
            // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
            // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
    
            // Create the SwiftUI view that provides the window contents.
            let contentView = ContentView().environmentObject(UserData())
    
            // Use a UIHostingController as window root view controller.
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = UIHostingController(rootView: contentView)
                self.window = window
                window.makeKeyAndVisible()
            }
        }
    
    }
    

    ContentView.swift

    struct ContentView: View {
        @ObservedObject var settings = UserSettings()
        @EnvironmentObject var userData: UserData
        @State var isShowActivity = false
        var body: some View {
            VStack {
                Text("Your score is \(settings.score)")
                Button(action: {
                    self.settings.score += 1
                    self.userData.isShowActivity = !self.userData.isShowActivity
                }) {
                    Text("Increase Score")
                }
                
                if userData.isShowActivity {
                    Text("TestView")
                }
                
                TestView()
            }
        }
    }
    
    struct TestView: View {
        @EnvironmentObject var userData: UserData
        
        var body: some View {
            HStack {
                if userData.isShowActivity {
                    Text("Change isShowActivity")
                }
            }
        }
    }
    
    class UserSettings: ObservableObject {
        @Published var score = 0
    }
    
    final class UserData: ObservableObject {
        @Published var isShowActivity = false
    }
    

    相关文章

      网友评论

          本文标题:SwiftUi的属性装饰器

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