Reputation: 1374
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?
Upvotes: 101
Views: 48113
Reputation: 1035
Without static
and dynamic.
struct MyView: View {
@Binding var date: Date
var body: some View {
DatePicker("Select date", selection: $date)
}
}
#Preview {
@Previewable @State var previewDate: Date = Date()
return MyView(date: $previewDate)
}
Upvotes: 0
Reputation: 337
if you have an object like viewModel you can also use .constant()
struct View_Previews: PreviewProvider {
static var previews: some View {
View(vm:.constant(ViewModel(text: "Sample Text")))
}
}
Upvotes: 0
Reputation: 117
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
Upvotes: 1
Reputation: 2615
I'm using different configurations of my view within one preview (I'm working on a custom control and want to see a different configuration of it). I've extended the implementation provided by @NeverwinterMoon in order to create multiple independent instances of a view.
struct SomeView: View {
@Binding var value: Int
var body: some View {
// some views modifying code binding
}
}
struct SomeView_Previews: PreviewProvider {
static var previews: some View {
VStack {
// The same view but with different configurations
// Configuration #1
PreviewWrapper() { value in
SomeView(value: value)
.background(Color.blue)
}
// Configuration #2
PreviewWrapper(initialValue: 2) { value in
SomeView(value: value)
.padding()
}
}
}
struct PreviewWrapper<Content: View>: View {
@State var value: Int
private let content: (Binding<Int>) -> Content
init(
initialValue: Int = 0,
@ViewBuilder content: @escaping (Binding<Int>) -> Content
) {
self.value = initialValue
self.content = content
}
var body: some View {
content($value)
}
}
}
Upvotes: 0
Reputation: 2451
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)
}
}
}
Upvotes: 83
Reputation: 3480
For your case, if you still would like to initialize your Binding variable you can use:
var binding: Binding = .constant(false)
Upvotes: 13
Reputation: 114846
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
Upvotes: 213