SwiftUi的属性装饰器

@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的属性装饰器)