How can I preview a SwiftUI button that depends on PresentationMode?

Viewed 619

How can I preview this button who needs a PresentationMode to get constructed? The button works well the main view that contains it creates it with an environment PresentationMode object declared as:

@Environment(\.presentationMode) var presentationMode:Binding<PresentationMode>
struct BackButton: View {
  @Binding var presentationMode: PresentationMode
  var color: Color
  var body: some View {
    Button(action: {
      self.$presentationMode.wrappedValue.dismiss()
    }, label: { Image(systemName: "chevron.left")
      .scaleEffect(1.3)
      .foregroundColor(color)
      .offset(x: -17)
      .frame(width: 43, height: 43)
    }
    )
  }
}

struct BackButton_Previews: PreviewProvider {
    static var previews: some View {
        let pres = PresentationMode()
      return BackButton(presentationMode: pres, color: .black) // Compiler Error: PresentationMode cannot be constructed because it has no accessible initializers
    }
}
1 Answers

I think PresentationMode should be declared as Environment Variable.

So declare it like this..

@Environment(\.presentationMode) var presentationMode

and then change it on action like that, as it is not a Binding anymore.

Button(action: {
    self.presentationMode.wrappedValue.dismiss()

Edit:

Here is a working example/ with preview for BackButton View and how to use PresentationMode.

struct MainView: View {
    var body: some View {
    
        NavigationView
        {
            VStack()
            {
                Text("Hello World")
                
                NavigationLink("Go to Detail View", destination: BackButton(color: .black))
        
            }.navigationBarTitle(Text("Main View"))
        }
    }
}


struct BackButton : View
{
    //Environment variable here
    @Environment(\.presentationMode) var presentationMode
    
    var color: Color
    
    var body: some View
    {
        Button(action: {
            //Dismiss the View
            self.presentationMode.wrappedValue.dismiss()
        }, label: { Image(systemName: "chevron.left")
          .scaleEffect(1.3)
          .foregroundColor(color)
          .offset(x: -17)
          .frame(width: 43, height: 43)
        })
    }
}

struct BackButton_Previews: PreviewProvider {
    static var previews: some View {
        //Preview here is working, no need to pass environment variable
        //Going back from this view in Preview won't work
        BackButton(color: .black)
    }
}
Related