SwiftUI绑定到计算属性



我有两个类,一个是显示数据源信息的ContentView。数据源是我的CharacterRepository。

我现在正在努力确保我的CharacterRepository中始终有一个排序列表。

这是我迄今为止的代码:

class CharacterRepository: ObservableObject {
@Published public var characters = [Character(name: "Nott the Brave",
initiative: 23,
isActive: false),
Character(name: "Caduceus Clay",
initiative: 2,
isActive: false),
...]
...
}

struct InitiativeTrackerScreen: View {
@EnvironmentObject var characterRepository: CharacterRepository
var body: some View {
NavigationView {
VStack {
List {
ForEach(characterRepository.characters) { entry in
CharacterListElement(character: entry)
}
...

现在,我想要的方法是将characters变量转换为一个计算属性,该属性在每次执行get时都会运行"sortedby"函数。不幸的是,绑定到计算属性在SwiftUI中还不可能(不确定,会不会?(。

有人能帮我做这个吗?我不想回到每次发生变化时都进行排序和重新绘制的旧方法。这并不是我使用带有ist甜蜜绑定的SwiftUI的原因。

我认为对属性getter中的数据进行排序可能是不必要的开销。

简单的(和注重性能的(解决方案是在数据更改时对其进行排序,然后更新@Published非计算属性并绑定到该属性:

class CharacterRepository: ObservableObject {
func updateCharacters(_ characters: [Character]) {
self.characters = characters.sorted() // or whatever sorting strategy you need...
}
@Published public var characters = [Character(name: "Nott the Brave",
initiative: 23,
isActive: false),
Character(name: "Caduceus Clay",
initiative: 2,
isActive: false),
...]
...
}

如果你更喜欢以性能为代价的纯粹主义者,那么你可以手动创建一个Binding——类似于这样的东西:

class CharacterRepository: ObservableObject {
let sortedCharacters: Binding<[Character]>
...

init() { 
self.sortedCharacters = .init(get: { return characters.sorted() }, set: { self.characters = $0 })
}
...
}

我喜欢通过相关问题来回答。为了什么,你曾经需要一些绑定到计算属性?

class CharacterRepository: ObservableObject {
@Published public var characters = [Character(name: "Nott the Brave",
initiative: 23,
isActive: false),
Character(name: "Caduceus Clay",
initiative: 2,
isActive: false),
...]
...
var sorted: [Character] {
characters.sorted()
}
}

就是你所需要的。

最新更新