@Binding 用于在父子視圖之間傳遞狀態(tài),實現(xiàn)雙向數(shù)據(jù)綁定的屬性包裝器。父視圖持有狀態(tài),而子視圖使用綁定來修改該狀態(tài)。這樣可以避免狀態(tài)重復并保持數(shù)據(jù)一致。
作用:@Binding用于在視圖之間傳遞和共享可讀寫的值。它創(chuàng)建了一個對屬性的引用,以便多個視圖可以共享同一份數(shù)據(jù),并且對數(shù)據(jù)的更改會在所有引用的地方生效。它做的事情是將值語義的屬性“轉換”為引用語義。對被聲明為 @Binding 的屬性進行賦值,改變的將不是屬性本身,而是它的引用,這個改變將被向外傳遞,使用@state可以實現(xiàn)在當前view視圖內(nèi)的狀態(tài)管理,但是如果需要將狀態(tài)傳遞到子視圖,并且實現(xiàn)雙向綁定就需要使用@Binding來實現(xiàn)。
應用場景
- @Binding 主要用于與支持雙向數(shù)據(jù)綁定的 UI 組件,如和 TextField、Stepper、Sheet 和 Slider 等配合使用。
- @Binding 適用于需要在子視圖中直接修改父視圖中的數(shù)據(jù)情況。
注意事項
- @Binding 不直接持有數(shù)據(jù),而是提供了對其他數(shù)據(jù)源的讀寫訪問的包裝。
- @Binding允許 UI 元素直接修改數(shù)據(jù),并反映這些數(shù)據(jù)的變化。
- 應當謹慎使用 @Binding,當子視圖只需響應數(shù)據(jù)變化而無需修改時,無需使用 @Binding。
- 在復雜的視圖層級中,逐級傳遞 @Binding 可能導致數(shù)據(jù)流難以追蹤,此時應考慮使用其他狀態(tài)管理方法。
- 確保 @Binding 的數(shù)據(jù)源是可信的,錯誤的數(shù)據(jù)源可能導致數(shù)據(jù)不一致或應用崩潰。由于 @Binding 只是一個管道,它并不保證對應的數(shù)據(jù)源在調(diào)用時必然存在。
- 開發(fā)者可以通過提供 get 和 set 的方式來自定義 Binding。
let binding = Binding<String>(
get: { text },
// 限制字符串的長度
set: { text = String($0.prefix(10)) }
)
使用示例
struct ParentView: View {
@State private var isOn = false
var body: some View {
ToggleView(isOn: $isOn)
}
}
struct ToggleView: View {
@Binding var isOn: Bool
var body: some View {
Toggle("Switch", isOn: $isOn)
}
}
在下面的示例中,父視圖通過 @Binding 將布爾值傳遞給子視圖,以控制子視圖的可見性。
struct ParentView: View {
@State private var isChildViewVisible = false
var body: some View {
VStack {
Toggle(isOn: $isChildViewVisible) {
Text("Show Child View")
}
if isChildViewVisible {
ChildView(isVisible: $isChildViewVisible)
}
}
}
}
struct ChildView: View {
@Binding var isVisible: Bool
var body: some View {
Text("Child View")
Button(action: {
isVisible = false
}) {
Text("Hide")
}
}
}