簡體   English   中英

SwiftUI 綁定到計算屬性?

[英]SwiftUI Binding to Computed Property?

我有兩個類,一個是顯示來自我的數據源的信息的 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 時都會運行“排序依據”函數。 不幸的是,在 SwiftUI 中還不能綁定到計算屬性(不確定,會不會?)。

有人可以幫我解決這個問題嗎? 我不想回到每次發生變化時排序和重繪的舊方法。 這不是我使用帶有甜蜜綁定的 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()
    }
}

是你所需要的全部。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM