在使用UIKit開發時,我們通常會拿到一個view的引用,然後通過這個引用去修改view的外觀。
但在SwiftUI中,所有view的外觀都是對“狀態”的響應,因此我們不會直接去修改view,而是修改“狀態”。
也就是說,我們只需要改變“狀態”,view檢測到變化並自動的刷新。
SwiftUI提供了幾種保存狀態的方式,來保證數據的“真實來源”(source of truth)。本文就來介紹它們各自的區別。
@State
@State修飾的數據只用於當前view內部使用,所以@State常與Private搭配使用。
而且通常用於修飾簡單的數據類型,如(Int, Double, String, Bool) 。
private @State var name: String = ""
@Binding
@Binding和@State搭配使用的,父view用@State,子view用@Binding,以實現父view和子view的數據綁定。
當數據是從外部傳遞的,並且需要和外部保持綁定時,就用@Binding修飾該變量。
@ObservedObject
和@State類似,但@ObservedObject用於修飾複雜的數據類型,而且只能修飾引用類型的數據。
所以,如果你想要修飾一個複雜的struct數據,首先需要用class來包裹這個struct。
final class MyClass: ObservableObject {
@Published var myStruct = MyComplexStruct()
}
//在view裏可以這樣定義
@ObservedObject var myClass = MyClass()
// myClass就像是被@State修飾的簡單數據。
可以用於組件之間的 數據傳遞。
@EnvironmentObject
如果對象存活於整個app生命週期,並且大量view需要共享此對象,那麼用@EnvironmentObject修飾就再好不過了(比如用戶信息對象)。
當然,你可以用@ObservedObject來達到同樣的目的,但你需要通過view1傳給view2,傳給view3...傳遞鏈條太長了。此時,用@EnvironmentObject就顯得方便許多了。
參考資料: