- Published on
@Binding — holatni bolalar view’lariga o’tkazish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Buni televizor pulti misolida tasavvur qiling. Pult televizor qaysi kanalda turganini saqlamaydi — bu ma'lumotni televizorning o'zi saqlaydi. Ammo pult kanalni o'zgartira oladi. Tugmani bosganingizda, pult televizorga buyruq yuboradi va televizor yangilanadi. Pult bog'lovchidir (binding): u boshqa joyda saqlanadigan qiymatni o'qiy oladi va yozadi.
Avvalgi (@State — Mahalliy View Holati) darsida siz @State har doim private deb belgilanishini o'rgandingiz, chunki unga faqat o'sha view egalik qilishi kerak. Ammo kodni toza va tushunarli saqlash uchun UI-ni bir nechta kichik view'larga bo'lganingizda va bola view (child view) ota view-ning (parent view) state'ini o'zgartirishi kerak bo'lganda nima bo'ladi? Aynan shu yerda @Binding yordamga keladi.
Ushbu darsning oxirida siz state egasi (state owner) va binding iste'molchisi (binding consumer) o'rtasidagi farqni, bola view-ga bog'liqlikni o'tkazish uchun $ prefiksidan qanday foydalanishni va bu pattern nima uchun ma'lumotlarni yagona yo'nalishda tartibli oqishini ta'minlashini tushunib olasiz.
Muammo: bo'lingan view'lar umumiy holatga muhtoj
Mana o'sha ota-bola view bog'lanishi misoli:
| Qator / Kod | Vazifasi |
|---|---|
@State private var isOn = false | Ota view (parent) ushbu qiymatga egalik qiladi. Bu haqiqat manbai (source of truth). Faqat shu view haqiqiy Bool qiymatini saqlaydi. |
ToggleRow(isOn: $isOn) | $ prefiksi state property-ni binding-ga aylantiradi va uni bola view-ga o'tkazadi. Bola view xotira nusxasini emas, balki ota view xotirasiga havola (reference) oladi. |
@Binding var isOn: Bool | Bola view binding qabul qilishini e'lon qiladi. private kalit so'zi va boshlang'ich qiymat yo'q — qiymat shu yerda emas, ota view-da yashaydi. |
$isOn bolada | Bola o'z navbatida ushbu binding-ni boshqa bir boshqaruvga (masalan, Toggle-ga) o'tkazganda yana $-dan foydalanadi — binding zanjir bo'ylab uzatiladi. |
Eng ko'p uchraydigan @Binding xatosi: Bola view-da
@Bindingo'rniga@Statee'lon qilish. Agar bola view@Stateishlatsa, u ma'lumotning o'ziga tegishli nusxasini yaratib oladi. Boladagi o'zgarishlar ota view-da ko'rinmaydi va natijada sizda bir-biriga zid bo'lgan ikkita haqiqat manbai paydo bo'ladi.
@Binding patternlari (Patterns)
$binding sintaksisi
// Ota view-da — $ belgisi @State xususiyatidan Binding yaratadi
ChildView(value: $myStateProperty)
// Bola view-da — @Binding bilan e'lon qilinadi, boshlang'ich qiymatsiz va private-siz
@Binding var value: String
$ prefiksi "menga ushbu state xususiyatiga bog'lanishni ber" degan ma'noni anglatadi. Bola view ikki tomonlama ulanishga ega bo'ladi: value-ni o'qish joriy qiymatni qaytaradi va value-ga yozish ota view-dagi @State-ni yangilaydi.
Binding.constant
// Previews-da bola view-ga binding uzatish kerak bo'lganda .constant() ishlatiladi
struct ToggleRow_Previews: PreviewProvider {
static var previews: some View {
// .constant qiymatni o'zgarmas binding bilan o'raydi — faqat o'qish uchun, preview-lar uchun juda qulay
ToggleRow(isOn: Binding.constant(true))
}
}
Binding.constant() metodidan preview-larda @Binding parametrini qondirish kerak bo'lganda foydalaniladi. U o'zgartirib bo'lmaydigan, faqat o'qish uchun mo'ljallangan bog'lanish yaratadi.
Ikki bosqichli Binding zanjiri
// Nevara view-gacha binding uzatish zanjiri
@State private var text = ""
ParentView(text: $text)
struct ParentView: View {
@Binding var text: String
var body: some View {
// Bola view-ga binding-ni uzatishda yana $ belgisidan foydalanamiz
ChildView(text: $text)
}
}
Binding-lar zanjir ko'rinishida juda yaxshi ishlaydi. Har bir daraja binding-ni keyingisiga $ yordamida uzatadi va eng yuqoridagi @State ma'lumotlar saqlanadigan yagona haqiqat manbai bo'lib qolaveradi.
Tayyor boshqaruv elementlariga Binding
@State private var volume: Double = 0.5
@State private var quantity = 1
VStack(spacing: 16) {
// Slider volume qiymatini binding orqali o'qiydi va yozadi
Slider(value: $volume, in: 0...1)
// Stepper quantity qiymatini binding orqali o'qiydi va yozadi
Stepper("Quantity: \(quantity)", value: $quantity, in: 1...10)
}
SwiftUI-ning foydalanuvchidan ma'lumot qabul qiluvchi tayyor boshqaruvlari — TextField, Toggle, Slider, Stepper, Picker, DatePicker — barchasi o'zgarishlarni yozib olish uchun binding qabul qiladi. Shuning uchun ularga ma'lumot uzatishda har doim $ belgisidan foydalanasiz.
Tezkor ma'lumotnoma
| Sintaksis | Vazifasi |
|---|---|
@Binding var x: Type | Binding e'lon qiladi — bu view x qiymatini o'qishi va yozishi mumkin, ammo saqlamaydi |
ChildView(x: $myState) | Ota view-dagi @State xususiyatidan bola view-ga binding uzatadi |
Binding.constant(value) | Faqat o'qish uchun mo'ljallangan binding — preview va testlar uchun qulay |
$binding bolada | Mavjud @Binding bog'liqlikni keyingi bola view-ga uzatadi |
x = newValue bolada | @Binding-ga yozish ota view-dagi @State-ni yangilaydi va qayta chizishni boshlaydi |
Topshiriq: rang tanlash paneli (color Picker Panel)
ColorSwatch deb nomlangan view yarating, unda uchta @State Double xususiyati bo'lsin: red, green va blue (har biri 0.5 dan boshlansin). Color(red: red, green: green, blue: blue) rangi bilan to'ldirilgan katta RoundedRectangle ko'rsating. Uning ostida alohida ColorSlider nomli view yarating, u String turidagi nom (label) va @Binding var value: Double qabul qilsin va ushbu nom bilan Slider-ni ko'rsatsin. Ota view-da uchta ColorSlider-dan foydalaning va ularga $red, $green va $blue qiymatlarini uzating. Sliderlarni sudrab yurganda to'rtburchak rangi jonli tarzda yangilanishi kerak.