Ang @Binding ay isang Property Wrapper sa SwiftUI na lumilikha ng referensya sa data na pag-aari ng ibang component. Hindi nag-iimbak ng halaga ang Binding nang mag-isa — nagbibigay lamang ito ng access sa umiiral na pinagmulan ng katotohanan sa pamamagitan ng $ projection. Ayon sa Apple Developer Documentation (2025), ang Binding ay nagbibigay ng reaktibong dalawang-daan na koneksyon sa pagitan ng parent at child view nang walang direktang pagmamay-ari ng data. @Binding ang pangunahing mekanismo para sa pagpasa ng nababagong estado pababa sa hierarchy.
Mga Pangunahing Punto
@Binding ay isang Property Wrapper na lumilikha ng dalawang-daan na koneksyon sa pagitan ng property na nakaimbak sa parent view at ng child component. Ang pangunahing pagkakaiba ng Binding sa @State: Hindi nagmamay-ari ng data ang Binding. Binabasa at isinusulat lamang nito ang halaga sa pamamagitan ng tunay na pinagmulan — @State, @StateObject, o ibang Binding sa parent. Kung walang Binding, hindi mababago ng mga child view ang estado ng ninuno nang walang callback o delegate.
Ang Binding ay ipinatupad bilang isang istraktura na may dalawang property: wrappedValue(kasalukuyang halaga) at projectedValue (ang Binding mismo, naa-access sa pamamagitan ng $). Kapag binago ng child view ang wrappedValue sa pamamagitan ng Binding, itinransmit ng SwiftUI ang pagbabago sa pinagmulan ng data at iredraw ang lahat ng nakadependeng view. Ito ay nangyayari nang sabay-sabay sa loob ng kasalukuyang cycle ng pag-update.
Mahalagang katangian: @Binding ay hindi limitado sa isang antas na pagpasa. Ang Binding ay maaaring ipasa sa pamamagitan ng maraming antas ng hierarchy — bawat child component ay tumatanggap ng referensya sa parehong pinagmulan ng data. Ang pagbabago sa anumang antas ay nagdudulot ng pinag-isang pag-update ng lahat ng naka-link na view.
Ang mekanismo ng dalawang-daan na koneksyon sa pamamagitan ng @Binding ay binuo sa projection ng Property Wrappers. Kapag nagdeklara ang parent ng @State var value: T, awtomatikong bumubuo ang SwiftUI ng projection na $value ng uri na Binding
struct SliderContainer: View {
@State private var value: Double = 0.5
var body: some View {
VStack {
Text("Halaga: \(value)")
SliderView(value: $value)
}
}
}
struct SliderView: View {
@Binding var value: Double
var body: some View {
Slider(value: $value, in: 0...1)
}
}
Sa halimbawa, ang SliderContainer ay nagmamay-ari ng @State value, at ang SliderView ay tumatanggap ng Binding sa pamamagitan ng $value. Ang Slider sa loob ng SliderView ay nakatali sa Binding na ito. Kapag hinila ang slider, binabago ng Slider ang halaga sa pamamagitan ng Binding, na awtomatikong nag-a-update ng @State sa SliderContainer, at parehong view ay nagpapakita ng kasalukuyang numero. Ang buong chain ay gumagana nang walang kahit isang callback o notipikasyon.
Para sa paggawa ng Binding mula sa @StateObject o @ObservedObject, ginagamit ang parehong projection: $object.property ay nagbibigay ng Binding
Bago ang SwiftUI, ang karaniwang paraan ng pagpasa ng mga pagbabago pataas sa hierarchy ay sa pamamagitan ng callback at delegate: ang parent ay nagpapasa ng closure, tinatawag ito ng child component kapag nagbago. Ang @Binding ay nag-aalok ng alternatibo na may mas kaunting code at mas deklaratibong syntax. Sa halip na magpasa ng completion closure, sapat na ang magpasa ng $stateValue.
| Kriterya | @Binding | Callback |
|---|---|---|
| Code | Isang annotation + $ | Closure + tawag |
| Multi-level | Awtomatiko | Chain ng mga closure |
| Pagsubok | Binding(value:constant) | Mock-closure |
| Pagkabasa | Mataas | Katamtaman |
| Flexibility | Data lang | Anumang lohika |
Gamitin ang @Binding kapag ang child view ay kailangan lamang magbasa at magbago ng halaga. Kung kinakailangan ang mga side action sa pagbabago (validation, pag-log, network request), pagsamahin ang Binding sa callback: ipasa ang Binding para sa data at closure para sa mga event. Halimbawa, ang TextField ay maaaring itali sa Binding, at ang onChange ay magsisimula ng validation.
@Binding ay inilalapat sa ilang tipikal na senaryo. Una — custom na kontrol: mga switch, slider, color picker, at iba pang interactive na elemento ay tumatanggap ng Binding para sa dalawang-daan na synchronization. Ikalawa — modal window: ang flag ng pagpapakita ng sheet ay ipinapasa bilang Binding, na nagpapahintulot sa child view na isara ang sarili sa pamamagitan ng presentationMode o direktang pagtatakda.
Ikatlong pattern — mga form na may paghihiwalay. Kung ang form ay binubuo ng maraming field, ang bawat field ay maaaring i-extract sa isang hiwalay na component na tumatanggap ng Binding para sa halaga nito. Pinapasimple nito ang pagsubok at muling paggamit ng mga field sa pagitan ng iba't ibang form. Ang parent component ay nananatiling nag-iisang may-ari ng buong modelo ng form.
struct FormField: View {
let title: String
@Binding var text: String
var body: some View {
VStack(alignment: .leading) {
Text(title).font(.caption)
TextField("Enter \(title.lowercased())", text: $text)
.textFieldStyle(.roundedBorder)
}
}
}
Ang component na FormField ay tumatanggap ng label at Binding sa isang string. Nagpapakita ito ng caption at TextField na nakatali sa ipinasa na Binding. Anumang form ay maaaring gumamit ng FormField nang maraming beses sa pamamagitan ng pagpasa ng $property para sa bawat field. Binabawasan nito ang pagdoble ng markup at isinasentro ang pag-style ng mga text field.
Pinapayagan ng SwiftUI ang manu-manong paggawa ng Binding sa pamamagitan ng initializer na Binding(get:set:). Ito ay kapaki-pakinabang kapag kailangan magdagdag ng lohika sa pagbasa o pagsulat ng halaga. Halimbawa, maaari kang lumikha ng Binding na nagfo-format ng numero bago i-save, o Binding na nagsi-sync ng halaga sa malayong server sa bawat pagbabago.
struct ValidatedField: View {
@State private var email: String = ""
var emailBinding: Binding<String> {
.init(
get: { email },
set: { email = $0.lowercased().trimmingCharacters(in: .whitespaces) }
)
}
var body: some View {
TextField("Email", text: emailBinding)
}
}
Sa listing, ang custom na emailBinding ay awtomatikong nagko-convert ng text sa maliit na titik at nag-aalis ng mga space sa bawat pagbabago. Ginagamit ng TextField ang Binding na ito sa halip na direktang pagbubuklod sa $email. Ang ganitong approach ay nagpapahintulot sa pagsentro ng validation at data transformation sa loob ng Binding, nang hindi nadudumihan ang code ng mga onChange handler.
Una at pinakakaraniwang error — pagpasa ng halaga sa halip ng Binding. Kung ang child component ay nagdeklara ng @Binding var text: String, at ang parent ay nagpasa ng text (walang $), ang compiler ay magbibigay ng error: Cannot convert value of type 'String' to expected argument type 'Binding
Pangalawang error — Binding sa read-only na data. Kung ang child view ay kailangan lamang magbasa ng halaga, huwag gumamit ng @Binding — sapat na ang ordinaryong let o @State mula sa parent. Ang Binding ay nagpapahiwatig ng posibilidad ng pagsulat, at ang mga dagdag na karapatan sa pagbabago ay nagpapahirap sa debugging at lumalabag sa prinsipyo ng minimal na pribilehiyo.
Pangatlong problema — Binding.constant sa produksyon. Ang Binding.constant(value) ay lumilikha ng pekeng pagbubuklod nang walang feedback — ang mga pagbabago ay hindi pinapansin. Gamitin ang constant para lamang sa prototyping at preview (Xcode Previews), ngunit hindi kailanman sa tunay na code. Para sa mga pagsubok, gamitin ang Binding(get:set:) na may kontroladong behavior.
Mga Madalas Itanong
@State ay nagmamay-ari ng data at namamahala ng kanilang imbakan sa heap. Ang @Binding ay tumutukoy lamang sa umiiral na estado nang walang pagmamay-ari. Ang @State ay palaging private, ang @Binding — input parameter ng child view.
Oo, sa pamamagitan ng initializer na Binding(get:set:) o Binding.constant(value). Ang Binding ay maaari ding makuha mula sa @StateObject sa pamamagitan ng projection na $object.$property at mula sa Publisher sa pamamagitan ng Binding(get:set:) sa loob ng Subscribe.
@Binding ay ipinapasa sa isang chain: bawat intermediate component ay nagdedeklara ng @Binding at ipinapasa ito sa pamamagitan ng $. Lahat ng antas ay tumutukoy sa isang pinagmulan ng data sa root view.
Binding.constant ay lumilikha ng tahimik na wrapper — binabalewala ng setter ang mga bagong halaga. Ito ay nilayon lamang para sa prototyping at SwiftUI Previews, kung saan hindi kinakailangan ang feedback mula sa child component.
Oo, ang Binding<T?> ay sinusuportahan. Kung magpasa ka ng Binding<String?>, ang child view ay maaaring magtakda ng nil. Ito ay maginhawa para sa mga opsyonal na field ng form o mga estado na may posibilidad ng pag-reset.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din