TextField输入未更新其他类(SwiftUI)中的@Published ObservedObject

时间:2019-11-29 11:58:24

标签: ios swift xcode swiftui

这是我为这两个课程编写的代码。我不确定这里发生了什么? 文本字段不会更新@Published'cityInput'变量。

我正在尝试让用户输入城市名称,然后使用该变量为他们输入的城市调用天气API。但是,当我打印或使用变量(cityInput)时,它仍然是默认值。它没有更新

import SwiftUI

struct ContentView: View {
   @ObservedObject var networkingManager = NetworkingManager()

   var body: some View {
      NavigationView {
          VStack {
            Text("Please Enter a City Name")
            TextField("City Name, i.e Sydney", text: $networkingManager.inputCity)
            NavigationLink(destination: ForecastView()) {
                    Text("Go")
                 }
            }
           .padding()
           .navigationBarTitle("Weather")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


import Foundation
import SwiftUI
import Combine

class NetworkingManager : ObservableObject {
    @Published var inputCity = "Sydney"
    @Published var weatherList = [WeatherInfoList]()
    var weatherCity = CityInformation(name: "Sydney", country: "AU")

    func load() {
        let apiKey = "d81d2f91438e7897ceb3c457c25"
        guard let url = URL(string: "https://api.openweathermap.org/data/2.5/forecast?q=Sydney&units=metric&APPID=\(apiKey)") else {
            return
        }
        print("City is: \(inputCity)")
        URLSession.shared.dataTask(with: url) { (data, response, err) in
            guard let data = data else { return }
            let weatherInfo = try! JSONDecoder().decode(WeatherAPIResponse.self, from: data)
            DispatchQueue.main.async {
                self.weatherCity = weatherInfo.city
                self.weatherList = weatherInfo.list
            }
        }.resume()
    }
}



import SwiftUI

struct ForecastView: View {
    @ObservedObject var networkingManager = NetworkingManager()

    var body: some View {
        NavigationView {
            VStack {
                List(networkingManager.weatherList, id: \.dt) { weather in
                    VStack(alignment: .leading) {
                        Text(weather.date)
                            .font(.headline)
                    Text("\(self.networkingManager.weatherCity.name), \(self.networkingManager.weatherCity.country)")
                    }
                    Spacer()
                    Text("\(weather.main.rTemp)°C ")
                    Image(systemName: "cloud.sun.fill") 
                }
            }.onAppear() {
                self.networkingManager.load()
            }
            .padding()
            .navigationBarTitle("Weather Forecast")
        }
    }
}

struct ForecastView_Previews: PreviewProvider {
    static var previews: some View {
        ForecastView()
    }
}

1 个答案:

答案 0 :(得分:1)

您不会回叫networkingManager.load()完成编辑后, 如果您打算在ForecastView()中显示预测详细信息,什么都不会改变?如果您尝试执行此操作,则需要使用@Binding var details或通过像这样通过网络管理员来传递它:

NavigationLink(destination: ForecastView(manager: networkingManager)) {
       Text("Go")
}

struct ForecastView: View {
    @ObservedObject var manager: NetworkingManager

    var body: some View {
        Text("Text").onAppear {
            self.manager.load()
        }
    }
}