提问人:Marius Bonifer 提问时间:10/26/2023 最后编辑:Marius Bonifer 更新时间:10/26/2023 访问量:91
如何将 .environment 全局绑定到所有 SwiftUI 预览?
How to Bind .environment Globally to All SwiftUI Previews?
问:
我有一个全局 DataManager,它保存了一个 NSManagedObjectContext:
class DataManager {
static let shared = DataManager()
var viewContext: NSManagedObjectContext
// ... Other code
}
应用程序本身一切正常。但是,我在使用 SwiftUI 预览时遇到了问题。目前,我正在为每个预览设置.environment
,如下所示:
#Preview {
let exampleModel = ExampleModel.create(context: DataManager.shared.viewContext)
return NavigationStack {
ExampleView(model: exampleModel)
}
.environment(\.managedObjectContext, DataManager.shared.viewContext)
}
在处理多个视图时,这种方法变得乏味。我正在寻找一种方法来为所有 SwiftUI 预览全局设置 .environment(\.managedObjectContext, DataManager.shared.viewContext)。
有没有更有效的方法来实现这一目标?
我做了一些研究,为预览创建一个包装器似乎是可行的。但是,我还没有找到允许我继续使用 #Preview 宏的解决方案。
答:
0赞
lorem ipsum
10/26/2023
#1
您可以使用所有注入和示例代码创建一个。ViewModifier
extension View {
func globalInjection() -> some View {
modifier(GlobalInjectionVM())
}
}
struct GlobalInjectionVM: ViewModifier {
let context: NSManagedObjectContext = DataManager.shared.viewContext
func body(content: Content) -> some View {
content
.environment(\.managedObjectContext, context)
}
}
然后,您需要做的就是在每次预览时调用。func
#Preview {
SampleView()
.globalInjection()
}
如果你想加强这一点,你可以用preview
protocol
protocol SampleProviderProtocol {
static func preview() -> Self
}
extension Item: SampleProviderProtocol {
static func preview() -> Self {
let new = Self(context: DataManager. shared.viewContext)
new.timestamp = Calendar.current.date(byAdding: .day, value: (-10...10).randomElement()!, to: Date())
return new
}
}
然后,您可以在ViewModifier
struct GlobalInjectionVM: ViewModifier {
let context: NSManagedObjectContext = DataManager.shared.viewContext
//Declare the types that you want to create samples
let types: [SampleProviderProtocol.Type] = [Item.self]
func body(content: Content) -> some View {
content
.environment(\.managedObjectContext, context)
.task {
//Iterate over the types
for type in types {
//Create 4 preview objects
for _ in 0...3 {
_ = type.preview()
}
}
}
}
}
确保在使用 Canvas 时使用“预览”上下文,您可以通过在加载商店之前将 url 设置为 null 来使用它。
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
评论
0赞
Marius Bonifer
10/26/2023
非常感谢:)这正是我一直在寻找的^^
评论
View