【问题标题】:SwiftUI: Sort list based on an @Published variableSwiftUI:基于@Published 变量的排序列表
【发布时间】:2020-05-13 00:09:38
【问题描述】:

我正在使用 SwiftUI 构建 UI,并且我有一个用于构建 List 元素的数组。现在我想根据来自@EnvironmentObject@Published 变量对该列表进行排序。

方法一

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

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 被设置为正确的对象。

【问题讨论】:

  • 您可以在此处复制可重现的代码示例吗?

标签: swift swiftui swiftui-list swiftui-environment


【解决方案1】:

您最好的方法可能是在每次数据更改时使用属性观察器对ObservableObject 中的列表进行排序,然后手动通知ObservableObject 发布者更改(而不是使用@Published,因此未排序的数组是更改之间没有短暂发布。)

直接在Viewbody 中进行排序不是一个好主意,因为在 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()
        }
    }

}

【讨论】:

  • 通过 SwiftUI 创建一个“即用型”的属性似乎确实是最好的方法。就我而言,我能够创建一个包含排序内容的新数组,发布并更新它。
  • 他们的 ObservableObject 在环境中,这可能意味着它是一个模型对象,如果视图不在屏幕上需要对数据进行排序,您将不希望进行排序。排序、格式化等应该在 View 结构中完成,如果出于其他原因需要引用类型,则应该在 View 拥有的 @StateObject 中完成。
猜你喜欢
  • 2021-09-07
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 2020-10-18
  • 2016-07-07
  • 1970-01-01
  • 2019-12-27
  • 2019-02-07
相关资源
最近更新 更多