Как преобразовать результаты запроса получения SwiftUI на основе связанных объектов?

Я создаю список SwiftUI, где мне нужен динамический предикат. Подход обсуждается здесь: https://www.hackingwithswift.com/books/ios-swiftui/dynamically-filtering-fetchrequest-with-swiftui

Вот мой код:

struct SomeView: View {

    var collection: Collection
    var messages: FetchRequest<Message>

    init(collection: Collection) {
        let predicate : NSPredicate = NSPredicate(format: "collection = %@", collection)
        self.collection = collection
        self.messages = FetchRequest<Message>(entity: Message.entity(), sortDescriptors: [NSSortDescriptor(key: "date", ascending: true)], predicate: predicate)
    }

    var body: some View {
        List(messages.wrappedValue, id: \.uniqueIdentifier) { message in
            // construct the UI
        }
    }
}

Все идет нормально.

Что я не могу понять, как это сделать: мне нужно преобразовать messagesэлементы, основанные на некоторых других сообщениях в результатах (скажем, на основе предыдущего сообщения для простоты). messages[0] должны выглядеть определенным образом. messages[1] вид зависит от messages[0]. messages[2] зависит от messages[1] и так далее. Я не могу рассчитать это заранее, так как со временем это может измениться. Он должен быть вычислен в контексте этого конкретного запроса / результата выборки.

Я мог бы выразить это как некоторое временное вычисляемое свойство объекта Message, которое затем может использовать код представления для разветвления. У меня может быть функция, в которой я передаю конкретное сообщение и массив сообщений, функция просматривает сообщение и другие сообщения и на основе этого устанавливает состояние данного сообщения. Однако SwiftUI ограничивает то, что я могу делать в коде просмотра, я не могу выполнять функции таким образом.

Я могу запустить карту или плоскую карту, где я получаю доступ к wrappedValue, но они не позволяют мне получать доступ к другим элементам коллекции для принятия решений (я так думаю?).

Как мне провести такую ​​трансформацию в этом контексте?

1 ответ

Решение

Если я правильно понял ваше описание (и с учетом того FetchedResults это RandomAccessCollection) Я бы пошел со следующим подходом

var body: some View {
    List(messages.wrappedValue, id: \.uniqueIdentifier) { message in
        rowView(for: message, from: messages.wrappedValue)
    }
}

func rowView(for message: Message, from result: FetchedResults<Message>) -> some View {
   // having .starIndex, .endIndex, .position, etc. do any dependent calculations here
   // and return corresponding View
}
Другие вопросы по тегам