在 SwiftUI 中,如何在 XcodePreview 中设置 editMode 的环境变量
Posted
技术标签:
【中文标题】在 SwiftUI 中,如何在 XcodePreview 中设置 editMode 的环境变量【英文标题】:In SwiftUI how do I set the environment variable of editMode in an XcodePreview 【发布时间】:2019-07-07 15:06:56 【问题描述】:给定这样的导航堆栈层次结构,其中编辑按钮被添加到另一个源文件中
struct ContentView : View
var body: some View
NavigationView
EditingView()
.navigationBarItems(trailing: EditButton())
使用编辑按钮的视图在代码库的其他地方
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())
能否以编程方式在预览中设置初始编辑模式?有没有办法在没有编辑按钮的情况下使用环境查看 EditingView?我发现工作的几种方法显示在 sn-p 中,但我希望我能找到一种方法来通过环境以编程方式设置和初始值。
#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
可以在此处找到示例项目: https://github.com/PaulWoodIII/PreviewEditMode
【问题讨论】:
作为记录,Binding
可以使用.constant(value)
代替实际值初始化为常量。所以.environment(\.editMode, .constant(.inactive))
可以设置环境变量。
【参考方案1】:
您可以通过添加到您的预览提供程序将其作为常量传递:
.environment(\.editMode, Binding.constant(EditMode.active))
例如:
struct EditingView_Previews : PreviewProvider
static var previews: some View
NavigationView
EditingView()
.environment(\.editMode, Binding.constant(EditMode.active))
【讨论】:
这在我的视图检查条件self.editMode?.wrappedValue == .active
时有效,但在使用内置 List
视图时无效。【参考方案2】:
环境变量editMode
是一个绑定。您可以通过编程方式进行设置,例如:
struct outerView: View
@State var editMode: EditMode = .active
var body: some View
return InnerView(model: model).environment(\.editMode, $editMode)
【讨论】:
【参考方案3】:我发现当有NavigationView
时“EditMode”不起作用,但我没有找到任何文档提及。
以下代码运行良好
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()
但是有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()
【讨论】:
【参考方案4】:这并不能解决能够设置EditMode
的环境值的问题,我也很想知道该怎么做,但更好的解决方法是在您的视图后面隐藏EditButton
正在预览:
struct ProfileHost_Previews : PreviewProvider
static var previews: some View
ZStack
EditButton().hidden()
ProfileHost()
假设您正在预览的视图已经具有切换编辑模式的方法,例如EditButton
。
【讨论】:
以上是关于在 SwiftUI 中,如何在 XcodePreview 中设置 editMode 的环境变量的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中停止 Animation().repeatForever
如何使用 SwiftUI 在 UICollectionViewCell 中填充内容
如何在 SwiftUI 的 ScrollView 中制作动画? SwiftUI 中的手风琴风格动画