SwiftUI:根据@Published 变量对列表进行排序

Bla*_*olf 5 swift swiftui swiftui-list swiftui-environment

我正在使用 SwiftUI 构建 UI,并且我有一个用于构建List元素的数组。现在我想根据@Published来自@EnvironmentObject.

方法一

我尝试让数组已经排序,将环境对象传递给排序方法:

List(getArraySorted(environmentObject)) { item in
    //do stuff with item
}
Run Code Online (Sandbox Code Playgroud)

这将编译,但如果environmentObject更改,列表将不会更新。我也试过传入environmentObject.variableToBaseSortOn但无济于事。

方法二

我尝试在 Swift UI 中对数组进行内联排序:

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

这将编译,但崩溃:

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

崩溃中的提示不正确,environmentObject已设置并self.environmentObject设置为正确的对象。

Bra*_*key 8

您最好的方法可能是在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()
        }
    }

}
Run Code Online (Sandbox Code Playgroud)