SwiftUI: список сортировки на основе переменной @Published - PullRequest
3 голосов
/ 27 января 2020

Я создаю пользовательский интерфейс с 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
}

Это скомпилирует, но cra sh:

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

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

1 Ответ

4 голосов
/ 27 января 2020

Ваш лучший подход, вероятно, состоит в том, чтобы сортировать список в пределах 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()
        }
    }

}
...