@Binding SwiftUI में एक Property Wrapper है जो दूसरे घटक के स्वामित्व वाले डेटा का संदर्भ बनाता है। Binding स्वयं मान संग्रहीत नहीं करता — यह केवल $ प्रक्षेपण के माध्यम से मौजूदा सत्य स्रोत तक पहुँच प्रदान करता है। Apple Developer Documentation (2025) के अनुसार, Binding डेटा के प्रत्यक्ष स्वामित्व के बिना पैरेंट और चाइल्ड व्यू के बीच प्रतिक्रियाशील द्वि-दिशात्मक संचार प्रदान करता है। @Binding पदानुक्रम में परिवर्तनीय स्थिति को नीचे भेजने के लिए मुख्य तंत्र है।
मुख्य बिंदु
@Binding एक Property Wrapper है जो पैरेंट व्यू में संग्रहीत प्रॉपर्टी और चाइल्ड घटक के बीच द्वि-दिशात्मक कनेक्शन बनाता है। Binding और @State के बीच मुख्य अंतर: Binding डेटा का स्वामित्व नहीं रखता। यह केवल सत्य स्रोत — @State, @StateObject या पैरेंट में किसी अन्य Binding के माध्यम से मानों को पढ़ता और लिखता है। Binding के बिना, चाइल्ड व्यू कॉलबैक या डेलिगेट के बिना पूर्वज स्थिति को संशोधित नहीं कर सकते थे।
Binding दो गुणों वाली संरचना के रूप में कार्यान्वित किया जाता है: wrappedValue (वर्तमान मान) और projectedValue (Binding स्वयं, $ के माध्यम से सुलभ)। जब चाइल्ड व्यू Binding के माध्यम से wrappedValue बदलता है, SwiftUI डेटा स्रोत में परिवर्तन का संचार करता है और सभी आश्रित व्यू को पुनः चित्रित करता है। यह वर्तमान अद्यतन चक्र के भीतर समकालिक रूप से होता है।
एक महत्वपूर्ण विशेषता: @Binding एकल-स्तरीय पासिंग तक सीमित नहीं है। Binding को कई पदानुक्रम स्तरों के माध्यम से पास किया जा सकता है — प्रत्येक चाइल्ड घटक उसी डेटा स्रोत का संदर्भ प्राप्त करता है। किसी भी स्तर पर परिवर्तन सभी बद्ध व्यू के एकल अद्यतन को ट्रिगर करता है।
@Binding के माध्यम से द्वि-दिशात्मक बाइंडिंग का तंत्र Property Wrapper प्रक्षेपणों पर बनाया गया है। जब पैरेंट @State var value: T घोषित करता है, SwiftUI स्वचालित रूप से Binding<T> प्रकार का $value प्रक्षेपण उत्पन्न करता है। $value को @Binding var value: T वाले चाइल्ड घटक में पास करके, आप दोनों व्यू को एक ही मेमोरी सेल से जोड़ते हैं। चाइल्ड व्यू में Binding के माध्यम से कोई भी लेखन दोनों घटकों के पुनः चित्रण को ट्रिगर करता है।
struct SliderContainer: View {
@State private var value: Double = 0.5
var body: some View {
VStack {
Text("Value: \(value)")
SliderView(value: $value)
}
}
}
struct SliderView: View {
@Binding var value: Double
var body: some View {
Slider(value: $value, in: 0...1)
}
}
उदाहरण में, SliderContainer @State value का स्वामी है, और SliderView $value के माध्यम से Binding प्राप्त करता है। SliderView के अंदर Slider इस Binding से बंधा है। स्लाइडर को खींचने पर, Slider Binding के माध्यम से मान बदलता है, जो स्वचालित रूप से SliderContainer में @State को अपडेट करता है, और दोनों व्यू वर्तमान संख्या प्रदर्शित करते हैं। पूरी श्रृंखला बिना किसी कॉलबैक या सूचना के काम करती है।
@StateObject या @ObservedObject से Binding बनाने के लिए, वही प्रक्षेपण उपयोग किया जाता है: $object.property Binding<PropertyType> देता है। यह पूरे ऑब्जेक्ट को पास किए बिना ObservableObject के व्यक्तिगत गुणों को चाइल्ड व्यू में पास करने की अनुमति देता है। यह दृष्टिकोण अधिक सटीक युग्मन प्रदान करता है और अनावश्यक पुनः चित्रण को रोकता है।
SwiftUI से पहले, पदानुक्रम में परिवर्तनों को ऊपर भेजने का मानक तरीका कॉलबैक और डेलिगेट था: पैरेंट एक क्लोज़र पास करता था, चाइल्ड घटक इसे परिवर्तन पर आमंत्रित करता था। @Binding कम कोड और अधिक घोषणात्मक सिंटैक्स के साथ एक विकल्प प्रदान करता है। पूर्णता क्लोज़र पास करने के बजाय, आप बस $stateValue पास करते हैं।
| मापदंड | @Binding | कॉलबैक |
|---|---|---|
| कोड | एक एनोटेशन + $ | क्लोज़र + आह्वान |
| बहु-स्तरीय | स्वचालित | क्लोज़र श्रृंखला |
| परीक्षण | Binding(value:constant) | मॉक क्लोज़र |
| पठनीयता | उच्च | मध्यम |
| लचीलापन | केवल डेटा | कोई भी तर्क |
@Binding का उपयोग करें जब चाइल्ड व्यू को केवल मान पढ़ने और संशोधित करने की आवश्यकता हो। यदि परिवर्तन पर साइड इफेक्ट आवश्यक हैं (मान्यकरण, लॉगिंग, नेटवर्क अनुरोध), Binding को कॉलबैक के साथ संयोजित करें: डेटा के लिए Binding और घटनाओं के लिए क्लोज़र पास करें। उदाहरण के लिए, एक TextField Binding से बंध सकता है, जबकि onChange मान्यकरण ट्रिगर करता है।
@Binding कई विशिष्ट परिदृश्यों में उपयोग किया जाता है। पहला — कस्टम नियंत्रण: स्विच, स्लाइडर, रंग चयनकर्ता और अन्य इंटरैक्टिव तत्व द्वि-दिशात्मक सिंक्रनाइज़ेशन के लिए Binding स्वीकार करते हैं। दूसरा — मोडल विंडो: शीट प्रदर्शन फ़्लैग Binding के रूप में पास किया जाता है, जिससे चाइल्ड व्यू presentationMode या प्रत्यक्ष सेटिंग के माध्यम से स्वयं को बंद कर सकता है।
तीसरा पैटर्न — पृथक्करण के साथ फ़ॉर्म. यदि एक फ़ॉर्म में कई फ़ील्ड हैं, प्रत्येक फ़ील्ड को एक अलग घटक में निकाला जा सकता है जो अपने मान के लिए Binding स्वीकार करता है। यह विभिन्न फ़ॉर्मों में फ़ील्ड के परीक्षण और पुन: उपयोग को सरल बनाता है। पैरेंट घटक पूरे फ़ॉर्म मॉडल का एकमात्र स्वामी बना रहता है।
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)
}
}
}
FormField घटक एक शीर्षक और एक स्ट्रिंग के लिए Binding स्वीकार करता है। यह एक लेबल और पास किए गए Binding से बद्ध TextField प्रदर्शित करता है। कोई भी फ़ॉर्म प्रत्येक फ़ील्ड के लिए $property पास करके FormField का कई बार उपयोग कर सकता है। यह मार्कअप दोहराव को कम करता है और टेक्स्ट फ़ील्ड स्टाइलिंग को केंद्रीकृत करता है।
SwiftUI Binding(get:set:) प्रारंभकर्ता के माध्यम से मैन्युअल रूप से Binding बनाने की अनुमति देता है। यह तब उपयोगी होता है जब मान पढ़ने या लिखने पर तर्क जोड़ने की आवश्यकता होती है। उदाहरण के लिए, एक Binding बनाया जा सकता है जो सहेजने से पहले संख्या को प्रारूपित करता है, या एक Binding जो प्रत्येक परिवर्तन पर मान को दूरस्थ सर्वर से सिंक करता है।
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)
}
}
सूची में, कस्टम emailBinding प्रत्येक परिवर्तन पर स्वचालित रूप से टेक्स्ट को लोअरकेस में बदलता है और रिक्त स्थान हटाता है। TextField $email से सीधे बंधने के बजाय इस Binding का उपयोग करता है। यह दृष्टिकोण onChange हैंडलर के साथ कोड को अव्यवस्थित किए बिना Binding के अंदर मान्यकरण और डेटा परिवर्तन को केंद्रीकृत करता है।
पहली और सबसे आम त्रुटि Binding के बजाय मान पास करना है। यदि कोई चाइल्ड घटक @Binding var text: String घोषित करता है, और पैरेंट text ($ के बिना) पास करता है, तो कंपाइलर त्रुटि देगा: Cannot convert value of type 'String' to expected argument type 'Binding<String>'. समाधान — पास करते समय हमेशा $ उपसर्ग का उपयोग करें: $text.
दूसरी त्रुटि — केवल-पढ़ने वाले डेटा पर Binding. यदि चाइल्ड व्यू को केवल मान पढ़ने की आवश्यकता है, तो @Binding का उपयोग न करें — पैरेंट से एक सरल let या @State पर्याप्त है। Binding लिखने की क्षमता का संकेत देता है, और अतिरिक्त संशोधन अनुमतियाँ डीबगिंग को जटिल बनाती हैं और न्यूनतम विशेषाधिकार के सिद्धांत का उल्लंघन करती हैं।
तीसरी समस्या — उत्पादन में Binding.constant. Binding.constant(value) फीडबैक के बिना एक डमी बाइंडिंग बनाता है — परिवर्तनों को अनदेखा किया जाता है। constant का उपयोग केवल प्रोटोटाइपिंग और पूर्वावलोकन (Xcode Previews) के लिए करें, लेकिन वास्तविक कोड में कभी नहीं। परीक्षणों के लिए, नियंत्रित व्यवहार के साथ Binding(get:set:) का उपयोग करें।
अक्सर पूछे जाने वाले प्रश्न
@State डेटा का स्वामी है और हीप में इसके भंडारण का प्रबंधन करता है। @Binding बिना स्वामित्व के केवल मौजूदा स्थिति को संदर्भित करता है। @State हमेशा निजी होता है, @Binding चाइल्ड व्यू का इनपुट पैरामीटर है।
हाँ, Binding(get:set:) प्रारंभकर्ता या Binding.constant(value) के माध्यम से। Binding को @StateObject से $object.$property प्रक्षेपण और Publisher से Subscribe के अंदर Binding(get:set:) के माध्यम से भी प्राप्त किया जा सकता है।
@Binding एक श्रृंखला के माध्यम से पास किया जाता है: प्रत्येक मध्यवर्ती घटक @Binding घोषित करता है और इसे $ के माध्यम से आगे पास करता है। सभी स्तर रूट व्यू में उसी डेटा स्रोत को संदर्भित करते हैं।
Binding.constant एक मूक आवरण बनाता है — सेटर नए मानों को अनदेखा करता है। यह केवल प्रोटोटाइपिंग और SwiftUI Previews के लिए है जहाँ चाइल्ड घटक से फीडबैक की आवश्यकता नहीं होती है।
हाँ, Binding<T?> समर्थित है। यदि आप Binding<String?> पास करते हैं, तो चाइल्ड व्यू nil सेट कर सकेगा। यह वैकल्पिक फ़ॉर्म फ़ील्ड या रीसेट विकल्प वाली स्थितियों के लिए सुविधाजनक है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें