使自定义 get {} set{} 像动态 proxy/shortcut 一样对数组中的不同对象起作用。 (斯威夫特用户界面)

Making custom get {} set{} to work like dynamic proxy/shortcut to different objects in Array. (SwiftUI)

我正在尝试实现类似绑定的双向功能。

我有一个模型,其中包含可识别的 Item 数组,var selectedID 持有选定 Item 的 UUID,而 var proxy 具有 get{} 通过 UUID 查找数组中的项目并 returns 它。

虽然 get{} 运行良好,但我无法弄清楚如何通过引用代理使 proxy 可变以更改所选 Item 的值。

我已经尝试实施 set{} 但没有任何效果。

import SwiftUI

var words = ["Aaaa", "Bbbb", "Cccc"]

struct Item: Identifiable {
    var id = UUID()
    var word: String
}

class Model: ObservableObject {
    @Published var items: [Item] = [Item(word: "One"), Item(word: "Two"), Item(word: "Three")]
    
    @Published var selectedID: UUID?
    
    var proxy: Item? {
        set {
            // how to set one property of Item?, but not the whole Item here?
        }
        get {
            let index = items.firstIndex(where: { [=11=].id == selectedID })
            return index != nil ? items[index!] : nil
        }
    }
}

struct ContentView: View {
    @StateObject var model = Model()
    var body: some View {
        VStack {
            // monitoring
            MonitorkVue(model: model)
            //selections
            HStack {
                ForEach(model.items.indices, id:\.hashValue) { i in
                    SelectionVue(item: $model.items[i], model: model)
                }
            }
        }.padding()
    }
}

struct MonitorkVue: View {
    @ObservedObject var model: Model
    var body: some View {
        VStack {
            Text(model.proxy?.word ?? "no proxy")
            
            // 3rd: cant make item change by referring to proxy
            // in order this to work, proxy's set{} need to be implemented somehow..
            Button {
                model.proxy?.word = words.randomElement()!
            } label: {Text("change Proxy")}
        }
    }
}

struct SelectionVue: View {
    @Binding var item: Item
    @ObservedObject var model: Model
    
    var body: some View {
        VStack {
            Text(item.word).padding()
            
            // 1st: making selection
            Button {
                model.selectedID = item.id } label: {Text("SET")
                }.disabled(item.id != model.selectedID ? false : true)
            
            // 2nd: changing item affects proxy,
            // this part works ok
            Button {
                item.word = words.randomElement()!
            }label: {Text("change Item")}
        }
    }
}

设置选择后,您可以随机化项目,代理将 return 新值。 但是当更改 module.proxy.word = "Hello" 会影响选定的 Item?

时,如何使它以相反的方式工作

有谁知道如何制作这条双向捷径? 谢谢

这是更正和一些修正:

struct Item: Identifiable {
    var id = UUID()
    var word: String
}



class Model: ObservableObject {
    
    @Published var items: [Item] = [Item(word: "One"), Item(word: "Two"), Item(word: "Three")]
    
    @Published var selectedID: UUID?
    
    var proxy: Item? {
        
        get {
            
            if let unwrappedIndex: Int = items.firstIndex(where: { value in (selectedID == value.id) }) { return items[unwrappedIndex] }
            else { return nil }
            
        }
        set(newValue) {
            
            if let unwrappedItem: Item = newValue {
                
                if let unwrappedIndex: Int = items.firstIndex(where: { value in (unwrappedItem.id == value.id) }) {
                    items[unwrappedIndex] = unwrappedItem
                }
                
            }
            
        }
        
    }
}