swift - 使自定义 get {} set{} 像动态代理/快捷方式一样工作,以访问 Array 中的不同对象。(斯威夫特用户界面)
问题描述
我正在尝试实现两种类似绑定的功能。
我有一个模型,其中包含一个可识别的数组Item
,varselectedID
持有一个 selected 的 UUID Item
,而 var通过 UUID 在数组proxy
中get{}
查找一个 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
?
有谁知道如何制作这种双向快捷方式?谢谢你
解决方案
这是一个更正和一些修复:
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
}
}
}
}
}
推荐阅读
- java - Java 服务器端:发送 Http POST 响应 - 仅状态
- angularjs - 角度控制器中未检测到框架物理碰撞事件
- java - 将十六进制字符串转换为 int (JAVA)
- cordova - 在没有用户交互的情况下读取文件时,Ionic App 中 resolveLocalFileSystemURL 上的“SECURITY_ERR”
- regex - 将子域重写为根/子域
- javascript - 在AXIOS之后更新静态?Vue JS
- haskell - 我真的可以从同一个包中构建和运行一个可执行文件作为测试套件的一部分吗?
- python-3.x - 获取空字典并输出到换行符
- php - 如何使用 php / laravel 从 wordpress 主题中识别外部 javascript、损坏的图像和 css 文件
- php - 表单数据未使用 laravel 5.4 版本提交到数据库