Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In SwiftUI how do I set the environment variable of editMode in an XcodePreview

Tags:

swift

swiftui

Given a navigation stack hierarchy like this where the edit button is added in another source file

struct ContentView : View {
  var body: some View {
    NavigationView {
      EditingView()
    }.navigationBarItems(trailing: EditButton())

  }
}

And the view that uses the edit button is elsewhere in the codebase

struct EditingView : View {

  @State var dataValue: String = "Initial Value"
  @Environment(\.editMode) var editMode

    var body: some View {
      VStack(alignment: .leading) {
        if self.editMode?.value == .inactive {
          Text(dataValue)
        } else {
          TextField(($dataValue))
        }
      }.padding()
        .navigationBarTitle("Lets edit some State")
        .navigationBarItems(trailing: EditButton())
  }
}

Can I programmatically set the initial editing mode in the preview? Is there a way to view the EditingView without an editing button using the environment? A few ways I have found that work are shown in the snippet but I would hope that I can find a method to set and initial value programmatically with the environment.

#if DEBUG
struct EditingView_Previews : PreviewProvider {
  static var previews: some View {
    NavigationView {
      VStack {
        EditingView()

        // I would prefer to use an environment variable.
        // Here is the best thought at some code:
        //
        //   `.environment(\.editMode, .inactive)`
        //
        // the compiler Error returned:
        // Type 'Binding<EditMode>?' has no member 'inactive'
        //
        // which I understand since it is a binding
        // not a direct access to an enum variable.
        // But can I set it somehow or should I let the system
        // handle it entirely?

        // So to get around the issue I have an extra edit button
        EditButton()

      }
    }
  }
  // Or this could work
  //.navigationBarItems(trailing: EditButton())
}
#endif

An Example project can be found here: https://github.com/PaulWoodIII/PreviewEditMode

like image 530
PaulWoodIII Avatar asked Jul 07 '19 15:07

PaulWoodIII


2 Answers

You can pass this in as a constant, by adding to your preview provider:

.environment(\.editMode, Binding.constant(EditMode.active))

e.g.:

struct EditingView_Previews : PreviewProvider {
  static var previews: some View {
    NavigationView {
      EditingView()
      }
    }
    .environment(\.editMode, Binding.constant(EditMode.active))
  }

}
like image 54
alistair Avatar answered Oct 02 '22 06:10

alistair


The environment variable editMode is a binding. You can set programmatically for example as follows:

struct outerView: View {
    @State var editMode: EditMode = .active

    var body: some View {
        return InnerView(model: model).environment(\.editMode, $editMode)
    }
}
like image 35
Klaus Thul Avatar answered Oct 02 '22 08:10

Klaus Thul