SwiftUI @Binding Initialize

2020-03-09 11:29发布

问题:

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?

回答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


回答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)
    }
  }
}


回答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)