SwiftUI: список сортировки на основе переменной @Published

Я создаю пользовательский интерфейс с помощью SwiftUI, и у меня есть массив, который я использую для создания Listэлемент. Теперь я хочу отсортировать этот список на основе@Published переменная, исходящая от @EnvironmentObject.

Подход 1

Я попытался получить уже отсортированный массив, передав объект среды методу сортировки:

List(getArraySorted(environmentObject)) { item in
    //do stuff with item
}

Это будет компилироваться, но список не будет обновляться, если environmentObjectизменения. Я также пробовал пройтиenvironmentObject.variableToBaseSortOn но безрезультатно.

Подход 2

Я попытался отсортировать массив, встроенный в Swift UI:

List(array.sorted(by: { (lhs, rhs) -> Bool in
    // do sorting based on self.environmentObject
})) { item in
    // do stuff with item
}

Это будет компилироваться, но выйдет из строя:

Fatal error: No ObservableObject of type EnvironmentObjectClass found.
A View.environmentObject(_:) for EnvironmentObjectClass may be missing as an ancestor of this view.

Подсказка в падении неверна, environmentObject установлен и self.environmentObject установлен на правильный объект.

1 ответ

Решение

Ваш лучший подход, вероятно, - отсортировать список внутри ObservableObject каждый раз, когда данные меняются с помощью обозревателя свойств, затем вручную информируя ObservableObject издатель изменения (вместо использования @Published, поэтому несортированный массив кратковременно не публикуется между изменениями.)

Не рекомендуется выполнять сортировку непосредственно в body из Viewпотому что этот блок может вызываться много-много раз по мере того, как его отображает SwiftUI (это прозрачно для нас, как разработчиков). Я подозреваю, что это может быть причиной того, что подход 2 не работает.

Например:

import Combine

class SomeObject: ObservableObject {

    // or whatever data type you need...
    var array: [String] {
        didSet {
            array.sort(by: { (lhs, rhs) -> Bool in
                // do sorting based on self.environmentObject
            })
            objectWillChange.send()
        }
    }

}
Другие вопросы по тегам