SwiftUI
Binding
Swift Programming
iOS Development
App Development

SwiftUI Binding Initialize

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

@Binding is one of SwiftUI’s core tools for passing mutable state from a parent view into a child view. It lets the child read and write a value that is owned somewhere else, which is essential for controls such as toggles, forms, and editors.

Most of the confusion around “binding initialize” comes from custom initializers. A @Binding property is not assigned the same way as a normal stored property, so the initializer has to target the binding storage correctly.

Basic @Binding Usage

The simplest case does not need a custom initializer at all.

swift
1import SwiftUI
2
3struct ParentView: View {
4    @State private var isEnabled = false
5
6    var body: some View {
7        ChildView(isEnabled: $isEnabled)
8    }
9}
10
11struct ChildView: View {
12    @Binding var isEnabled: Bool
13
14    var body: some View {
15        Toggle("Enabled", isOn: $isEnabled)
16    }
17}

The parent owns the source of truth through @State, and the child receives a binding using the $ prefix.

Why Custom Initialization Feels Different

Suppose your child view needs both a binding and a normal parameter. A common first attempt is this:

swift
1init(title: String, isEnabled: Binding<Bool>) {
2    self.title = title
3    self.isEnabled = isEnabled   // compile error
4}

That fails because isEnabled is the wrapped value, not the binding storage. The correct target is the underscored storage property.

The Correct Pattern for Initializing a Binding

Use _propertyName inside the initializer.

swift
1import SwiftUI
2
3struct SettingsRow: View {
4    let title: String
5    @Binding var isEnabled: Bool
6
7    init(title: String, isEnabled: Binding<Bool>) {
8        self.title = title
9        self._isEnabled = isEnabled
10    }
11
12    var body: some View {
13        Toggle(title, isOn: $isEnabled)
14    }
15}

The key line is:

swift
self._isEnabled = isEnabled

That assigns the incoming Binding<Bool> to the property-wrapper storage instead of trying to assign it to the wrapped Bool value.

Using the View from a Parent

The parent still passes the binding with $:

swift
1import SwiftUI
2
3struct ParentView: View {
4    @State private var notificationsEnabled = true
5
6    var body: some View {
7        SettingsRow(
8            title: "Notifications",
9            isEnabled: $notificationsEnabled
10        )
11    }
12}

This is the standard parent-child data flow in SwiftUI. The child edits the parent’s state without owning it.

Constant Bindings for Previews and Read-Only Cases

Sometimes you want a view that requires a binding, but you are using it in a preview or test where no live state exists. In that case, use Binding.constant.

swift
1#Preview {
2    SettingsRow(
3        title: "Notifications",
4        isEnabled: .constant(true)
5    )
6}

A constant binding is useful for previews, but it is read-only in practice. The UI may render, but changes do not propagate back to mutable state because there is none.

Initializing Derived Bindings

You can also create a binding manually from getter and setter closures. This is useful when the child view should edit part of a larger model.

swift
1import SwiftUI
2
3struct ProfileView: View {
4    @State private var username = "mark"
5
6    var body: some View {
7        let uppercasedBinding = Binding<String>(
8            get: { username.uppercased() },
9            set: { username = $0.lowercased() }
10        )
11
12        TextField("Username", text: uppercasedBinding)
13    }
14}

This is more advanced, but it shows that a Binding is a value with read and write behavior, not just syntax sugar.

Common Pitfalls

The most common mistake is trying to assign a Binding<T> directly to a @Binding var in a custom initializer. The fix is to assign to the underscored storage property, such as _isEnabled.

Another issue is forgetting the $ when passing a state variable from the parent. isEnabled is the value, while $isEnabled is the binding.

It is also easy to use .constant(...) in places where you actually expect edits to persist. Constant bindings are useful for previews, but they are not a substitute for real mutable state.

Finally, choose @Binding only when the child should edit state owned by another view. If the child owns the value itself, @State is usually the right tool instead.

Summary

  • '@Binding lets a child view read and write state owned by another view.'
  • In a custom initializer, assign the incoming binding to the underscored storage property such as _isEnabled.
  • Parents pass bindings using the $ prefix on @State values.
  • 'Binding.constant(...) is useful for previews and non-editable scenarios.'
  • Use @Binding only when the child should mutate external state rather than own the state itself.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.