@Binding — apa itu, cara kerja dan contoh di SwiftUI

Penulis: IT Sectr Diterbitkan: 2026-06-19 Waktu membaca: 7 mnt

@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 — Property Wrapper untuk membuat referensi ke status tampilan induk
  • Tanpa kepemilikan — Binding tidak menyimpan data, hanya menyediakan akses ke sumber kebenaran
  • Proyeksi $ — $stateValue membuat Binding dari @State atau @StateObject
  • Koneksi dua arah — perubahan di tampilan anak langsung tercermin di induk
  • Binding.constant — nilai tetap untuk pembuatan prototipe tanpa umpan balik

Apa itu @Binding di SwiftUI?

@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.

Bagaimana cara kerja koneksi dua arah Binding

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. Dengan melewatkan $value ke komponen anak dengan @Binding var value: T, Anda menghubungkan kedua tampilan ke satu sel memori. Setiap penulisan melalui Binding di tampilan anak menyebabkan penggambaran ulang kedua komponen.

swift
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. Ini memungkinkan melewatkan properti individual ObservableObject ke tampilan anak tanpa melewatkan seluruh objek. Pendekatan seperti ini memberikan ikatan yang lebih sempit dan mencegah penggambaran ulang yang tidak perlu.

@Binding vs callback: mana yang harus dipilih

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@BindingCallback
KodeSatu anotasi + $Closure + panggilan
Multi-levelOtomatisRantai closure
PengujianBinding(value:constant)Mock-closure
KeterbacaanTinggiSedang
FleksibilitasHanya dataLogika 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.

Pola penggunaan @Binding di proyek

@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.

swift
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.

Membuat Binding khusus

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.

swift
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 dan antipattern dengan @Binding

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'. Solusi — selalu gunakan prefiks $ saat melewatkan: $text.

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

Apa perbedaan antara @Binding dan @State?

@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.

Bisakah Binding dibuat tanpa @State?

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.

Bagaimana cara melewatkan Binding melalui beberapa tingkat bersarang?

@Binding dilewatkan dalam rantai: setiap komponen perantara mendeklarasikan @Binding dan melewatkannya lebih lanjut melalui $. Semua tingkat merujuk ke satu sumber data di tampilan akar.

Mengapa Binding.constant tidak memperbarui antarmuka?

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.

Bisakah @Binding bersifat opsional?

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

  • @Binding — Property Wrapper untuk koneksi dua arah dengan data tampilan induk
  • Tidak memiliki data — hanya menyediakan akses ke sumber kebenaran
  • Proyeksi $ mengubah @State, @StateObject menjadi Binding untuk dilewatkan ke tampilan anak
  • Binding kustom dibuat melalui Binding(get:set:) dengan logika tambahan
  • Binding.constant — hanya untuk pratinjau dan prototipe
  • Transmisi multi-level — Binding melewati kedalaman bersarang apa pun
  • Alternatif untuk callback — cara deklaratif mengubah status dari komponen anak

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.

Diskusikan proyek

Baca juga