Передача основных данных FetchedResults <T> для предварительного просмотра в SwiftUI

У меня есть родительский вид, который @FetchRequest и проходит FetchedResults<T>к детскому представлению. Все работает, и дочернее представление может анализировать черезFetchedResults. Однако я не могу понять, как настроить данные так, чтобы ребенокPreviewstruct будет работать. Как правильно настроить постоянные данные вPreview struct, чтобы я мог создать дочерний вид и передать FetchedResults<T>?

2 ответа

Как FetchedResults<T> это RandomAccessCollection и быстрый массив также является RandomAccessCollection, вот возможное решение.

Протестировано с Xcode 11.4 / iOS 13.4

struct ContentView: View {
    @Environment(\.managedObjectContext) var context
    @FetchRequest(entity: Person.entity(), sortDescriptors: [])
        var result: FetchedResults<Person>

    var body: some View {
        VStack(alignment: .leading) {
            Text("Persons").font(.title)
            PersonsView(results: result) // FetchedResults<Person> is a collection
        }
    }
}

// generalize PersonsView to depend just on collection
struct PersonsView<Results:RandomAccessCollection>: View where Results.Element == Person {
    let results: Results
    var body: some View {
        ForEach(results, id: \.self) { person in
            Text("Name: \(person.name ?? "<unknown>")")
        }
    }
}

struct ChildView_Previews: PreviewProvider {
    static var previews: some View {
        PersonsView(results: [Person()]) // << use regular array to test
    }
}

Обновление: исправлена ​​и протестирована часть для Xcode 12 / ISO 14 (из-за сбоя вышеупомянутого PreviewProvider)

Похоже, теперь сущность должна быть прочитана и указана явно:

struct ChildView_Previews: PreviewProvider {
    static let entity = NSManagedObjectModel.mergedModel(from: nil)?.entitiesByName["Person"]

    static var previews: some View {
        let person = Person(entity: entity!, insertInto: nil)
        person.name = "Test Name"

        return PersonsView(results: [person])
    }
}

Используйте предварительный просмотр PersistenceController в предварительно созданной структуре PersistenceController (внутри файла «Persistence.swift»).

поэтому, если вы передаете элемент из объекта Core Data «Item»:

      struct ContentView: View {
...
private var items: FetchedResults<Item>
..
ForEach(items) { item in
DetailView(item: item)
}
..

В Detail-View сделайте следующее:

      
struct DetailView: View {
    var item: FetchedResults<Item>.Element
    
    var body: some View {
        Text("Items text = \(item.text ?? "")")
    }
}

struct Detail_Previews: PreviewProvider {

    static var previews: some View {
        let viewContext = PersistenceController.preview.container.viewContext
        let previewItem = Item(context: viewContext)
        previewItem.text = "Text4preview"
        
        return Detail(item: previewItem)
    }
}
Другие вопросы по тегам