@Binding adalah Property Wrapper di SwiftUI yang membuat referensi ke data yang dimiliki oleh komponen lain. Binding tidak menyimpan nilai secara mandiri — ia hanya menyediakan akses ke sumber kebenaran yang ada melalui proyeksi $. Menurut Apple Developer Documentation (2025), Binding menyediakan koneksi dua arah reaktif antara tampilan induk dan anak tanpa kepemilikan data secara langsung. @Binding adalah mekanisme kunci untuk melewatkan status yang dapat diubah ke bawah hierarki.
Poin Utama
@Binding adalah Property Wrapper yang membuat koneksi dua arah antara properti yang disimpan di tampilan induk dan komponen anak. Perbedaan utama Binding dengan @State: Binding tidak memiliki data. Ia hanya membaca dan menulis nilai melalui sumber sebenarnya — @State, @StateObject, atau Binding lain di induk. Tanpa Binding, tampilan anak tidak dapat mengubah status leluhur tanpa callback atau delegat.
Binding diimplementasikan sebagai struktur dengan dua properti: wrappedValue (nilai saat ini) dan projectedValue (Binding itu sendiri, dapat diakses melalui $). Ketika tampilan anak mengubah wrappedValue melalui Binding, SwiftUI mentransmisikan perubahan ke sumber data dan menggambar ulang semua tampilan yang bergantung. Ini terjadi secara sinkron dalam siklus pembaruan saat ini.
Fitur penting: @Binding tidak terbatas pada transmisi satu tingkat. Binding dapat dilewatkan melalui beberapa tingkat hierarki — setiap komponen anak menerima referensi ke sumber data yang sama. Perubahan di tingkat mana pun menyebabkan pembaruan terpadu dari semua tampilan yang terkait.
Mekanisme koneksi dua arah melalui @Binding dibangun di atas proyeksi Property Wrapper. Ketika induk mendeklarasikan @State var value: T, SwiftUI secara otomatis menghasilkan proyeksi $value bertipe Binding
struct SliderContainer: View {
@State private var value: Double = 0.5
var body: some View {
VStack {
Text("Nilai: \(value)")
SliderView(value: $value)
}
}
}
struct SliderView: View {
@Binding var value: Double
var body: some View {
Slider(value: $value, in: 0...1)
}
}
Dalam contoh, SliderContainer memiliki @State value, dan SliderView menerima Binding melalui $value. Slider di dalam SliderView terikat ke Binding ini. Saat menarik penggeser, Slider mengubah nilai melalui Binding, yang secara otomatis memperbarui @State di SliderContainer, dan kedua tampilan menampilkan angka saat ini. Seluruh rantai bekerja tanpa satu pun callback atau pemberitahuan.
Untuk membuat Binding dari @StateObject atau @ObservedObject, proyeksi yang sama digunakan: $object.property menghasilkan Binding
Sebelum SwiftUI, cara standar untuk melewatkan perubahan ke atas hierarki adalah melalui callback dan delegat: induk melewatkan closure, komponen anak memanggilnya saat terjadi perubahan. @Binding menawarkan alternatif dengan lebih sedikit kode dan sintaksis yang lebih deklaratif. Alih-alih melewatkan closure penyelesaian, cukup melewatkan $stateValue.
| Kriteria | @Binding | Callback |
|---|---|---|
| Kode | Satu anotasi + $ | Closure + panggilan |
| Multi-level | Otomatis | Rantai closure |
| Pengujian | Binding(value:constant) | Mock-closure |
| Keterbacaan | Tinggi | Sedang |
| Fleksibilitas | Hanya data | Logika apa pun |
Gunakan @Binding ketika tampilan anak hanya perlu membaca dan mengubah nilai. Jika diperlukan tindakan sampingan saat perubahan (validasi, pencatatan, permintaan jaringan), gabungkan Binding dengan callback: lewatkan Binding untuk data dan closure untuk peristiwa. Misalnya, TextField dapat terikat ke Binding, dan onChange akan memulai validasi.
@Binding diterapkan dalam beberapa skenario umum. Pertama — kontrol kustom: sakelar, penggeser, pemilih warna, dan elemen interaktif lainnya menerima Binding untuk sinkronisasi dua arah. Kedua — jendela modal: flag tampilan sheet dilewatkan sebagai Binding, memungkinkan tampilan anak menutup dirinya sendiri melalui presentationMode atau pengaturan langsung.
Pola ketiga — formulir dengan pemisahan. Jika formulir terdiri dari banyak bidang, setiap bidang dapat diekstrak ke komponen terpisah yang menerima Binding untuk nilainya. Ini menyederhanakan pengujian dan penggunaan kembali bidang di berbagai formulir. Komponen induk tetap menjadi satu-satunya pemilik seluruh model formulir.
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)
}
}
}
Komponen FormField menerima label dan Binding ke string. Ini menampilkan keterangan dan TextField yang terikat ke Binding yang dilewatkan. Formulir apa pun dapat menggunakan FormField berkali-kali dengan melewatkan $property untuk setiap bidang. Ini mengurangi duplikasi markup dan memusatkan penataan gaya bidang teks.
SwiftUI memungkinkan pembuatan Binding secara manual melalui inisialisasi Binding(get:set:). Ini berguna ketika perlu menambahkan logika saat membaca atau menulis nilai. Misalnya, Anda dapat membuat Binding yang memformat angka sebelum disimpan, atau Binding yang menyinkronkan nilai dengan server jarak jauh pada setiap perubahan.
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)
}
}
Dalam listing, emailBinding kustom secara otomatis mengonversi teks ke huruf kecil dan menghapus spasi pada setiap perubahan. TextField menggunakan Binding ini alih-alih ikatan langsung ke $email. Pendekatan seperti ini memungkinkan pemusatan validasi dan transformasi data di dalam Binding, tanpa mengotori kode dengan handler onChange.
Kesalahan pertama dan paling umum — melewatkan nilai alih-alih Binding. Jika komponen anak mendeklarasikan @Binding var text: String, dan induk melewatkan text (tanpa $), kompiler akan memberikan kesalahan: Cannot convert value of type 'String' to expected argument type 'Binding
Kesalahan kedua — Binding pada data hanya-baca. Jika tampilan anak hanya perlu membaca nilai, jangan gunakan @Binding — cukup let biasa atau @State dari induk. Binding menyiratkan kemungkinan penulisan, dan hak modifikasi tambahan mempersulit debugging dan melanggar prinsip hak istimewa minimum.
Masalah ketiga — Binding.constant di produksi. Binding.constant(value) membuat ikatan palsu tanpa umpan balik — perubahan diabaikan. Gunakan constant hanya untuk pembuatan prototipe dan pratinjau (Xcode Previews), tetapi jangan pernah dalam kode nyata. Untuk pengujian, gunakan Binding(get:set:) dengan perilaku terkontrol.
Pertanyaan yang Sering Diajukan
@State memiliki data dan mengelola penyimpanannya di heap. @Binding hanya merujuk ke status yang ada tanpa kepemilikan. @State selalu private, @Binding — parameter masukan tampilan anak.
Ya, melalui inisialisasi Binding(get:set:) atau Binding.constant(value). Binding juga dapat diperoleh dari @StateObject melalui proyeksi $object.$property dan dari Publisher melalui Binding(get:set:) di dalam Subscribe.
@Binding dilewatkan dalam rantai: setiap komponen perantara mendeklarasikan @Binding dan melewatkannya lebih lanjut melalui $. Semua tingkat merujuk ke satu sumber data di tampilan akar.
Binding.constant membuat pembungkus diam — setter mengabaikan nilai baru. Ini hanya ditujukan untuk pembuatan prototipe dan SwiftUI Previews, di mana umpan balik dari komponen anak tidak diperlukan.
Ya, Binding<T?> didukung. Jika Anda melewatkan Binding<String?>, tampilan anak dapat mengatur nil. Ini berguna untuk bidang formulir opsional atau status dengan kemungkinan pengaturan ulang.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga