@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) প্রতিক্রিয়া ছাড়া একটি ডামি বাইন্ডিং তৈরি করে — পরিবর্তনগুলি উপেক্ষা করা হয়। শুধুমাত্র প্রোটোটাইপিং এবং প্রিভিউ (Xcode Previews)-এর জন্য constant ব্যবহার করুন, কিন্তু বাস্তব কোডে কখনই নয়। পরীক্ষার জন্য, নিয়ন্ত্রিত আচরণ সহ 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন