首页 > 解决方案 > 使自定义 get {} set{} 像动态代理/快捷方式一样工作,以访问 Array 中的不同对象。(斯威夫特用户界面)

问题描述

我正在尝试实现两种类似绑定的功能。

我有一个模型,其中包含一个可识别的数组Item,varselectedID持有一个 selected 的 UUID Item,而 var通过 UUID 在数组proxyget{}查找一个 Item 并返回它。

虽然get{}效果很好,但我不知道如何通过引用代理proxy来改变 selected 的值。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: { $0.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")}
        }
    }
}

设置选择后,您可以随机化项目,代理将返回新值。module.proxy.word = "Hello"但是,当更改会影响 selected时,如何使其以相反的方式工作Item

有谁知道如何制作这种双向快捷方式?谢谢你

标签: swiftswiftuibindinggetset

解决方案


这是一个更正和一些修复:

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
                }
                
            }
            
        }
        
    }
}

推荐阅读