将@Published数据传递到Textfield()的最简单方法?

时间:2020-01-14 21:18:50

标签: swiftui combine

场景:
我正在使用一个Observable类从网络获取数据。
在这种情况下,一些基本天气数据。

问题:
我不知道如何在调用视图中显示此数据。

就目前而言,我只是想填充一个Textfield(并且稍后会担心更精致的布局)。

我得到以下信息:

... / StandardWeatherView.swift:22:13:无法为调用初始化程序 类型为'TextField <_>',参数类型为'(Text,text: 样本?)'

这是我的调用视图,它是@ObservedObject数据的接收者:

import SwiftUI

struct StandardWeatherView: View {
    @EnvironmentObject var settings: Settings
    @ObservedObject var standardWeatherReportLoader = StandardWeatherReportLoader()

    init() {
        self.standardWeatherReportLoader.doStandard()
    }

    var body: some View {
        ZStack {
            Color("FernGreen").edgesIgnoringSafeArea(.all)
            TextField(Text("Weather Data"), text: standardWeatherReportLoader.weatherReport)
        }
    }
}

struct StandardWeatherView_Previews: PreviewProvider {
    static var previews: some View {
        StandardWeatherView()
    }
}

这是发布者,正在获取数据:

import Foundation

class StandardWeatherReportLoader: ObservableObject {
    @Published var networkMessage: String?
    @Published var hasAlert = false
    @Published var weatherReport: Sample?
    @Published var hasReport = false

    func doStandard() {
        let url = EndPoint.weather.path()
        var request = URLRequest(url: EndPoint.weather.path()!)
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let task = URLSession.shared.dataTask(with: url!) { (data: Data?, _: URLResponse?, error: Error?) -> Void in
            DispatchQueue.main.async {
                guard error == nil else {
                    self.networkMessage = error?.localizedDescription
                    self.hasAlert = true
                    return
                }

                do {
                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    let result = try decoder.decode(Sample.self, from: data!)
                    self.weatherReport = result
                    self.hasReport = true
                    print("\n Standard Weather ----------------")
                    print(#function, "line: ", #line, "Result: ",result)
                    print("\n")
                } catch let error as NSError {
                    print(error)
                }
            }
        }
        task.resume()
    }
}

通过@Published var将数据字符串传递给View的最简单方法是什么?

日志:

标准天气---------------- doStandard()行:38结果: 样本(坐标:DataTaskPubTab.Coord(lon:-0.13,lat:51.51),天气: [DataTaskPubTab.Weather(id:300,main:“ Drizzle”,description:“ light 强度毛毛雨“)],基本:”站“,主要: DataTaskPubTab.Main(温度:280.32,压力:1012,湿度:81, tempMin:279.15,tempMax:281.15),可见度:10000,风向: DataTaskPubTab.Wind(速度:4.1,度:80),云: DataTaskPubTab.Clouds(全部:90),dt:1485789600.0,id:2643743,名称: “伦敦”)

但是我在TextField上没有了:

(lldb)po standardWeatherReportLoader.weatherReport nil

1 个答案:

答案 0 :(得分:1)

一种选择是在您的体内设置绑定,以在TextField更新时进行跟踪。在此绑定中,您可以根据需要编辑发布的变量:

@ObservedObject var reportLoader = StandardWeatherReportLoader()

var body: some View {

        // Binding to detect when TextField changes
        let textBinding = Binding<String>(get: {
            self.reportLoader.networkMessage
        }, set: {
            self.reportLoader.networkMessage = $0
        })

        // Return view containing the text field
        return VStack {

                TextField("Enter the Network Message", text: textBinding)
        }
}

编辑:同样在您的原始帖子中,您正在将可选类型Sample的对象传递到TextField中,该对象期望使用绑定的String类型,这可能会引起一些问题。