SwiftUI @Binding Initialize

35,343

Solution 1

When you use your LoggedInView in your app you do need to provide some binding, such as an @State from a previous view or an @EnvironmentObject.

For the special case of the PreviewProvider where you just need a fixed value you can use .constant(false)

E.g.

#if DEBUG
struct LoggedInView_Previews : PreviewProvider {
    static var previews: some View {
        LoggedInView(dismissView: .constant(false))
    }
}
#endif

Solution 2

Using Binding.constant(false) is fine but only for static previews. If you actually wanna launch a Live Preview, constant will not behave the same way as the real case as it will never be updated by your actions. I personally use Live Preview a lot, as I can play around with an isolated view.

Here is what I do for previews requiring Binding:

import SwiftUI

struct SomeView: View {
   @Binding var code: String

   var body: some View {
     // some views modifying code binding
   }
}

struct SomeView_Previews: PreviewProvider {
  static var previews: some View {
    PreviewWrapper()
  }

  struct PreviewWrapper: View {
    @State(initialValue: "") var code: String

    var body: some View {
      SomeView(code: $code)
    }
  }
}

Solution 3

  • If you need a simple property that belongs to a single view you should use @State
  • If you need to have complex property that may belong to several view(like 2-3 views) you shall use @ObjectBinding
  • Lastly, if you need to have property that needs to use all around views you shall use @EnvironmentObject. Source for detail information

For your case, if you still would like to initialize your Binding variable you can use:

var binding: Binding = .constant(false)

Solution 4

In preview you have to use .constant(Bool(false)):

#if DEBUG
struct LoggedInView_Previews : PreviewProvider {
    static var previews: some View {
        LoggedInView(dismissView: .constant(Bool(false))
    }
}
#endif
Share:
35,343
DonBaron
Author by

DonBaron

Updated on January 23, 2022

Comments

  • DonBaron
    DonBaron over 2 years

    Been playing around with SwiftUI and understood the concept of BindableObjects etc so far (at least I hope I do).

    I bumped into a stupid problem I can't seem to find an answer for: How do you initialize a @Binding variable?

    I have the following code:

    struct LoggedInView : View {
    
        @Binding var dismissView: Bool
    
        var body: some View {
            VStack {
                Text("Hello World")
            }
        }
    }
    

    In my preview code, I want to pass that parameter of type Binding<Bool>:

    #if DEBUG
    struct LoggedInView_Previews : PreviewProvider {
        static var previews: some View {
            LoggedInView(dismissView: **Binding<Bool>**)
        }
    }
    #endif
    

    How would I go an initialize it? tried:

    Binding<Bool>.init(false)
    Binding<Bool>(false)
    

    Or even:

    @Binding var dismissView: Bool = false
    

    But none worked... any ideas?

  • Martin R
    Martin R almost 5 years
    That looks elegant. I just wonder if it makes the property immutable for the live preview.
  • Paulw11
    Paulw11 almost 5 years
    It is, but that is typically all you need for the preview
  • NeverwinterMoon
    NeverwinterMoon over 4 years
    For a static preview, using immutable Binding.constant is fine, but it is totally unusable for a Live Preview where I wanna play around with just one view and see the value changed.
  • Noyer282
    Noyer282 over 4 years
    The solution of @NeverwinterMoon below is better, because it lets you interact with the canvas.
  • bcause
    bcause about 4 years
    This works. But I'm wondering why adding a property like @State static var code: String = "" isn't enough?
  • NeverwinterMoon
    NeverwinterMoon about 4 years
    It isn't enough as it doesn't work, unlike the proposed solution. With static var the property value just doesn't get updated and it works the same way as using Binding.constant - which is fine for a static preview only.
  • Ethan Halprin
    Ethan Halprin about 3 years
    NeverwinterMoon I've used this in my code and it works like a charm (I needed a @State since I had a Binding<> call). Gave answer +1
  • Admin
    Admin over 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.