[英]SwiftUI – @State vs @Binding
我正在學習 iOS 使用 Swift 和 SwiftUI 進行編程。我知之甚少,而且我對@State
和@Binding
之間的區別感到非常困惑。
如果我理解正確,@Binding 在技術上@State
@Binding
它不會更新視圖。 如果是這樣,那么如果我可以使用@State
來做同樣的事情,為什么我需要@Binding
呢?
@State
和@Binding
都是屬性包裝器。
@狀態
@捆綁
SwiftUI 是一個聲明式的面向組件的框架。 您必須忘記 MVC,其中控制器在視圖和 model 之間進行調解。 SwiftUI 使用 diffing 算法來了解更改並僅更新相應的視圖。
@狀態
@捆綁
@環境對象
將State
視為您視圖的唯一真實來源,作為變異變量並使視圖無效以反映 state 的手段。
另一方面, Binding
是視圖與其底層 model 之間的雙向連接。 一種改變不受視圖管理的State
的方法(例如,反映和控制控件本身不知道其存儲或來源的布爾值的Toggle
)
最后,您可以使用$
前綴運算符從任何State
獲取Binding
。
在它們之間進行選擇的簡單指南是:
我是否需要修改我私有的值? => State
我需要修改其他視圖的 State 嗎? => 綁定
State
@State
關鍵字允許我們詢問 SwiftUI 來監控屬性的值。 一旦值發生變化, View
將失效並以有效的方式再次呈現。@propertyWrapper
。捆綁
@Binding
和$
-prefix 允許將State
屬性傳遞給嵌套的子對象。@Binding
另一個顯式依賴於@propertyWrapper
的 @propertyWrapper。Binding
屬性包裝器,您可以定義對事實源的顯式依賴而不擁有它,此外,您不需要指定初始值,因為綁定可以從 state 派生。供您參考的鏈接: Medium
我想提供一個非常簡短的“實際用途”解釋,這有助於我清除它。 我沒有定義狀態/綁定,我只是指出了很大的區別。
@State
擁有價值,即“真相的來源”@Binding
傳遞值,用作管道。關於@State的一件重要事情:更改將觸發重繪。 更改@State的值將導致整個視圖“重新執行”。
State簡單屬性,如 string、整數和布爾值 屬於單個視圖 - 標記為私有
綁定復雜的屬性,如自定義類型在許多視圖中共享數據。 引用類型需要
在其他地方創建的EnvironmentObject屬性(例如共享數據)如果丟失,應用程序將崩潰。
Here is the notes I have prepared for myself,
@State:
@Binding:
Thanks!
想象一下您有兩個 SwiftUI 視圖的情況。 在第一個視圖中,您聲明了一個count
變量,在第二個視圖中,您創建了一個Tap Me
按鈕。 單擊按鈕時,應更新第一個視圖中的count
。 要實現此邏輯,您需要在第一個視圖中使用@State
屬性包裝器,並在第二個視圖中使用@Binding
屬性包裝器。
@State
允許在本地操作少量value type
的數據。 @State
直接創建和管理值,因此它是Source of Truth
。 @Binding
也指的是value type
的數據,但屬於不同的視圖。 @Binding
不是事實的來源。 為了將@State
屬性提供給Binding<T>
您需要使用$
運算符(即它看起來像$count
)。 @Binding
在屬性和另一個視圖之間創建雙向連接。
這是代碼:
import SwiftUI struct FirstView: View { @State private var count: Int = 0 var body: some View { ZStack { Color.black.ignoresSafeArea() VStack { SecondView(counter: $count).frame(width: 300, height: 100) Text("Tapped \(count) times").foregroundColor(.white) } } } } struct SecondView: View { @Binding var counter: Int var body: some View { ZStack { Color.yellow Text("Tap Me").onTapGesture { counter += 1 } } } }
除了前面提到的屬性包裝器之外,借助所謂的“三位一體”套件—— @StateObject
、 @Published
和@ObservedObject
,也可以實現類似的結果。
下面的 pivot 表代表了 15 個常用的 SwiftUI 4.0 屬性包裝器的主要特性。
# | 屬性包裝器 | 真理之源 | 它是干什么用的? | 類型 |
---|---|---|---|---|
01 | @AppStorage | 是的 | 從 UserDefaults 讀取/寫入 | 價值 |
02 | @捆綁 | 不 | 創建雙向連接 | 價值 |
03 | @環境 | 不 | 從系統中讀取數據 | |
04 | @環境對象 | 不 | 從多個視圖中讀取共享的 object | 參考 |
05 | @FetchRequest | 是的 | 將其用於 CoreData 獲取請求 | |
06 | @FocusedBinding | 不 | 在關鍵視圖中監視值 | 價值 |
07 | @FocusedValue | 不 | @FocusedBinding 的簡單版本 | 價值 |
08 | @手勢狀態 | 是的 | 存儲活動手勢的值 | 價值 |
09 | @命名空間 | 是的 | 創建一個 animation 命名空間 | |
10 | @ObservedObject | 不 | 指符合 ObservableObject 的外部 class 的實例 | 參考 |
11 | @已發布 | 是的 | 附加到 ObservableObject 內部的屬性 | 參考 |
12 | @ScaledMetric | 是的 | 讀取用戶的動態類型設置 | 價值 |
13 | @SceneStorage | 是的 | 恢復系統狀態的輕量級數據 | 價值 |
14 | @狀態 | 是的 | 在本地操作視圖的數據 | 價值 |
15 | @StateObject | 是的 | 存儲一個符合 ObservableObject 的新實例 | 參考 |
@State 和@Binding 將變量轉換為流。 帶有@State 的變量是一個事件源,每次修改它時都會產生“值已更改”。 默認情況下,此事件連接到“更新視圖”,因此每次修改變量時,都會引發事件並刷新視圖。
帶有 @Binding 的變量充當source和sink ,因此您可以將另一個變量的事件“綁定”到其中。 當您通過 $ 將變量傳遞給視圖時,您要求 swiftUI 將 $thisVairable 的事件提供給 @Binding 變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.