【问题标题】:SwiftUI - too many previewsSwiftUI - 太多预览
【发布时间】:2021-06-28 13:20:26
【问题描述】:

如何只为我的视图显示 1 个预览?现在我的一个视图有问题:ItemView.swift

在我运行 ContentView.swift 的实时预览并添加一些核心数据对象后,我的 ItemView.swift 会显示所有对象和测试数据的预览。有很多对象,有很多预览,这会大大降低 Xcode 的速度。

我在代码 2 中标记了可能导致问题的地方。我认为它是 ForEach 或 ItemView_Previews 结构。我试图修复它,但我不能。

我正在使用核心数据。并有 1 个实体:项目,具有 1 个属性:日期。但我认为这不是核心数据问题。

ContentView.swift

import SwiftUI
import CoreData

struct ContentView: View {
    
    @Environment(\.managedObjectContext) var managedObjectContext
    @State var paidFilter :Bool? = nil
    
    
    var body: some View {
        
        NavigationView {
            List {
                
                ItemView(filter: paidFilter)
                
            }
            .listStyle(PlainListStyle())
            .navigationTitle(Text("Items"))
            .navigationBarItems(
                trailing:
                    
                    Button(action: {
                        let item = Item(context: self.managedObjectContext)
                        item.date = Date()
                        
                        do {
                            try self.managedObjectContext.save()
                        }catch{
                            print(error)
                        }
                        
                    }) {
                        Image(systemName: "plus.circle.fill")
                            .font(.title)
                    }
            )
        }
        .navigationViewStyle(StackNavigationViewStyle())
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        return ContentView()
            .environment(\.managedObjectContext, context)
    }
}

ItemView.swift

import SwiftUI

struct ItemView: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    var fetchRequest: FetchRequest<Item>
    var items: FetchedResults<Item> { fetchRequest.wrappedValue }
    
    init(filter: Bool?) {
        fetchRequest = FetchRequest<Item>(entity: Item.entity(), sortDescriptors: [])
    }
    
    var body: some View {
        // I think problem is here
        ForEach(items, id: \.self) {item in
            Text("\(item.date ?? Date())")
        }       
    }
}

struct ItemView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        //Or problem is here - Test data
        let testItem = Item.init(context: context)
        testItem.date = Date()
        return ItemView(filter: false)
            .environment(\.managedObjectContext, context)
    }
}

【问题讨论】:

  • 首先重构您的应用程序委托,以便将核心数据内容移动到一个单独的类中,然后添加运行内存版本的 sqlite 而不是普通版本的能力。然后,您可以拥有存储的内存版本,其中只有几个项目。这已经写了很多次了,所以做一些研究,我相信你会找到一些好的文章。
  • 那么你的意思是解决方案是在 Core Data 中使用一些占位符,而不是实际的对象?
  • 不,它与普通的核心数据存储完全一样,具有相同类型的托管对象,但它只存在于内存中,因此任何更改都会在应用退出时消失。
  • 我在想问题出在我的观点中的数据流上。或者也许有一些方法可以在 Preview strict 中提供测试值,完全忽略 Core Data
  • 你当然可以这样做,但你需要在两者之间添加一些层,而不是直接针对 NSManagedObjectContext

标签: ios swift swiftui preview


【解决方案1】:

替换

var body: some View {
    // I think problem is here
    ForEach(items, id: \.self) {item in
        Text("\(item.date ?? Date())")
    }       
}

var body: some View {

    /// add VStack here!
    VStack {
        ForEach(items, id: \.self) {item in
            Text("\(item.date ?? Date())")
        }       
    }
}

如果没有 VStack 或其他容器,您的主体将由多个视图组成。这使得 Xcode 为它们中的每一个生成一个预览...有关类似问题,请参阅 here

【讨论】:

  • 谢谢!几乎完美。我只看到您修复的 1 个预览。但是我不知道为什么项目数量增加了一倍。在 ContentView.swift 中添加了 5 个对象,ItemView.swift 的预览显示了 10 个项目。你知道这可能是什么问题吗?
  • @mallow 尝试Command + F 并搜索“ItemView”。您可能在某处有一个额外的
  • 谢谢@aheze,我已经检查过了。它不会在任何地方重复。我已经发布了关于这个问题的新问题:stackoverflow.com/questions/66913812/… 我想我应该先解决它,然后我会回复你回答这个问题。因为我不确定我的代码是否有问题,或者是否有更好的方法来处理预览?非常感谢您尝试帮助我。
  • 谢谢@aheze。您的解决方案有效。添加 VStack 后,我只能看到 1 个预览。我仍然有更多项目的原因是因为我用于预览的代码使用在实时预览中创建的核心数据对象和我定义为 testItems 的内存对象。我以前没有意识到这一点。我在想它只使用内存中的测试项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-09
相关资源
最近更新 更多