【问题标题】:How binding between computed property in model and view's @Binding property in SwiftUI如何绑定模型中的计算属性和 SwiftUI 中视图的 @Binding 属性
【发布时间】:2020-10-24 13:33:44
【问题描述】:

我正在尝试制作一个关于 restful 的 API Tester 应用程序。我的模型存储了一些属性,方案协议如“http”,主机如“www.google.com”,路径如“/search”和查询参数如“?q=keyword”。 和一个关于 URL 字符串的计算属性,它是从上面存储的属性中加入的。

class ModelStore: ObservableObject {
        
        @Published var scheme = “http”
        @Published var host = ""
        @Published var port = "80"
        @Published var path = ""
        @Published var query = "" 
        
        var urlString: String {
            get {
                var tempUrl: String
                tempUrl =  scheme + “://” + host + ":" + port + "?" + query
                return tempUrl
            }
            set {
                guard let url = URL(string: newValue) else {
                    return
                }
                scheme = url.scheme ?? ""
                host = url.host ?? ""
                path = url.path
                query = url.query ?? ""
            }
        }
    
        var parametersArray: [String] {
            get {
                query.components(separatedBy: "&")
            }
            set {
                query = newValue.joined(separator: "&")
            }
        }
        
        var paramStruct: [ParaStruct] {
            get {
                var params = [ParaStruct]()
                parametersArray.forEach { (str) in
                    let item = str.components(separatedBy: "=")
                    if item.count > 1 {
                        params.append(ParaStruct(key: item[0], value: item[1]))
                    }
                }
                return params
            }
            set {
                var newQuery = [String]()
                newValue.forEach { (value) in
                    let item = value.key + "=" + value.value
                    newQuery.append(item)
                }
                query = newQuery.joined(separator: "&")
            }
        }
    }

class ParaStruct: Identifiable, ObservableObject{
    var id = UUID()
    static func == (lhs: ParaStruct, rhs: ParaStruct) -> Bool {
        lhs.key == rhs.key && lhs.value == rhs.value
    }
    @Published var key: String = ""
    @Published var value: String = ""
    init(key: String, value: String) {
        self.key = key
        self.value = value
    }
}

struct ContentView: View {
    @ObservedObject var modelStore = ModelStore()
    var body: some View {
        GeometryReader { geometryProxy in
            VStack(spacing: 0) {
                TextField("URL", text: self.$modelStore.urlString) 
                TextField("Host", text: self.$modelStore.host)
                TextField("Port", text: self.$modelStore.portString)
                TextField("Path", text: self.$modelStore.path)
                TextField("Query Parameters", text: self.$modelStore.query)
                
                List(self.modelStore.paramStruct) { (param) in
                    TextField("value", text: Binding(get: {
                        param.value
                    }, set: { (value) in

//this textfield doesn't work in here????
                        param.value = value
                    }))
                }
            }
        }
    }
}

到目前为止一切正常,但 List 中的文本字段不起作用。它可以从模型中读取更新,但无法将文本字段的更改写入模型,导致其他视图不同步。

set: { (value) in
//this textfield doesn't work in here????
                  param.value = value
     }

它有什么问题?也许我理解错了?有人帮帮我吗?

【问题讨论】:

  • 无关,但最好不要重新发明轮子,而是使用基金会的URLComponents

标签: ios swift binding swiftui observableobject


【解决方案1】:

试试下面的

TextField("value", text: Binding(get: {
    param.value
}, set: { (value) in
    self.modelStore.objectWillChange.send()     // << this !!
    param.value = value
}))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多