【问题标题】:Simplest way to pass @Published data to a Textfield()?将@Published 数据传递给 Textfield() 的最简单方法?
【发布时间】:2020-05-01 15:50:20
【问题描述】:

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

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

暂时,我只是想填充一个文本字段(稍后会担心更精致的布局)。

我得到以下信息:

.../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将数据字符串传递给视图的最简单方法是什么?

日志:

标准天气 ---------------- doStandard() 行:38 结果: 示例(坐标:DataTaskPubTab.Coord(经度:-0.13,纬度:51.51),天气: [DataTaskPubTab.Weather(id: 300, main: "细雨", description: "光 强度毛毛雨")],基地:“车站”,主要: DataTaskPubTab.Main(温度:280.32,压力:1012,湿度:81, tempMin:279.15,tempMax:281.15),能见度:10000,风: DataTaskPubTab.Wind(速度:4.1,度:80),云: DataTaskPubTab.Clouds(all: 90), dt: 1485789600.0, id: 2643743, name: “伦敦”)

但是我在 TextField 中得到了零:

(lldb) po standardWeatherReportLoader.weatherReport nil

【问题讨论】:

  • 不清楚您的期望...TextField.text 需要Binding&lt;String&gt; 但您尝试将Sample 传递给自定义类型。

标签: swiftui combine


【解决方案1】:

一个选项是在您的正文中设置一个绑定,以便在 TextField 更新时进行跟踪。在此绑定中,您可以根据需要编辑 Published 变量:

@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 类型,这可能会导致一些问题。

【讨论】:

  • 是的,我注意到了。传递 Sample 的实际字符串组件确实有效。所以我要么处理整个对象,要么处理零碎的字符串。但我更喜欢使用这些对象。我会研究你的建议。谢谢。
  • 实际上,我正在尝试从 reportLoader 获取信息;不从视图中设置其值。似乎更容易从 reportLoader 中传播信息并将位以可散列实体(如字符串与可绑定对象)的形式发送回视图。
猜你喜欢
  • 2015-12-20
  • 1970-01-01
  • 2019-10-02
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 2011-05-13
  • 2012-03-19
  • 2010-10-06
相关资源
最近更新 更多