在 SwiftUI 中,如何在 XcodePreview 中设置 editMode 的环境变量

Pau*_*III 8 swift swiftui

给定这样的导航堆栈层次结构,其中将编辑按钮添加到另一个源文件中

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

  }
}
Run Code Online (Sandbox Code Playgroud)

使用编辑按钮的视图在代码库的其他地方

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())
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以在预览中以编程方式设置初始编辑模式吗?有没有办法使用环境在没有编辑按钮的情况下查看 EditingView?代码片段中显示了我发现工作的几种方法,但我希望我能找到一种方法来以编程方式使用环境设置和初始值。

#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
Run Code Online (Sandbox Code Playgroud)

可以在此处找到示例项目:https : //github.com/PaulWoodIII/PreviewEditMode

小智 10

您可以通过添加到您的预览提供程序将其作为常量传递:

.environment(\.editMode, Binding.constant(EditMode.active))
Run Code Online (Sandbox Code Playgroud)

例如:

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

}
Run Code Online (Sandbox Code Playgroud)


小智 9

环境变量editMode是一个绑定。例如,您可以通过编程方式进行设置,如下所示:

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

    var body: some View {
        return InnerView(model: model).environment(\.editMode, $editMode)
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 9

我发现当存在 时“EditMode”不起作用NavigationView,但我没有找到任何引用它的文档。下面的代码运行良好

struct ContentView: View {
    @Environment(\.editMode)  var mode

    var body: some View {
        HStack {
            if self.mode?.wrappedValue == .active {
                Button("Cancel") {
                    self.mode?.animation().wrappedValue = .inactive
                }
            }

            Spacer()
            EditButton()
        }
    }    
}

Run Code Online (Sandbox Code Playgroud)

但是当有NavigationView时它不起作用

struct ContentView: View {
    @Environment(\.editMode)  var mode

    var body: some View {
        NavigationView {
            HStack {
                if self.mode?.wrappedValue == .active {
                    Button("Cancel") {
                        self.mode?.animation().wrappedValue = .inactive
                    }
                }

                Spacer()
                EditButton()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ric*_*lis -2

这并不能解决能够设置 的环境值的问题EditMode,我也很想知道如何做到这一点,但一个稍微好一点的解决方法是隐藏EditButton您正在预览的视图后面:

struct ProfileHost_Previews : PreviewProvider {
    static var previews: some View {
        ZStack {
            EditButton().hidden()
            ProfileHost()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

假设您正在预览的视图已经具有切换编辑模式的方法,例如EditButton.