DismissAction for Preview

325 Views Asked by At

I am trying to solve an issue with DismissAction in Preview. This is in the View: let parentDismiss: DismissAction

This is what I have in Preview:

struct MilkingView_Previews: PreviewProvider {
    static var previews: some View {
        MilkingView(parentDismiss: DismissAction())
    }
}

But I constantly have an error 'DismissAction' cannot be constructed because it has no accessible initializers

DismissAction() doesn't help as well as DismissAction.

3

There are 3 best solutions below

5
Yrb On

This should be enough to make the preview build, if you simply need to provide a function, but don't need it to actually do anything:

struct MilkingView_Previews: PreviewProvider {
    static var previews: some View {
        MilkingView(parentDismiss: {})
    }
}

if you do, you can always do something like:

struct MilkingView_Previews: PreviewProvider {
    static var previews: some View {
        MilkingView(parentDismiss: {
            print("Doing something...")
        })
    }
}

There is no need to do more than this. It is a preview provider showing just part of the UI.

0
Apollo On

I don't know how to solve your problem the right way, but I am using a workaround, and it works for me.

So, bear with me.

I have a .sheet that has a view inside. That view has a list of NavigationLink items, and they will open a form in a third view. From that form I should be able to close the sheet.

So..

Main view > List (in a sheet) > Form (close from here)

So on my list view I have this:

@Environment(\.dismiss) var dismiss
// (...)
NavigationLink {
    MyForm(something, dismissParent: dismiss)
} label: {
    Text(title)
}

On my form view, that lives inside that list, I pass my dismiss into the initialiser. The init originally looked like this:

private var dismissParent: DismissAction

init(_ something, dismissParent: DismissAction) {
    self.something = something
    self.dismissParent = dismissParent
}

Of course, that breaks the preview, as your own code. What I did was pass a closure as a callback. So I modified my code, like so:

private var dismissParent: () -> Void

init(_ something, dismissParent: @escaping () -> Void) {
    self.something = something
    self.dismissParent = dismissParent
}

On the parent I got this:

@Environment(\.dismiss) var dismiss
// (...)
NavigationLink {
    MyForm(something) {
        dismiss()
    }
} label: {
    Text(title)
}

And on the preview I do:

#if DEBUG
struct MyForm_Previews: PreviewProvider {
    static var previews: some View {
        ZStack {
            MyForm(
                dummySomething,
                dismissParent: {}
            )
        }
    }
}
#endif

I use that ZStack there because preview for some reason seems to break a lot when I'm dealing with views in sheets. I don't know why, but this fixes it.

I also use annotation #if DEBUG and #endif because I realised that the preview code is compiled in some situations and it bloats the app needlessly. I use that to exclude preview from the final code. (I don't know if that was fixed or not, I don't have time or patience to pursue this kind of information, but it doesn't break my code, so I'm happy.)

It works for me. Try that.

0
Baker2795 On

For other's who come across this. Define your dismiss action in the struct as a static property.

@Environment(\.dismiss) static private var dismiss