简体   繁体   中英

TextField Input not updating @Published ObservedObject in other class (SwiftUI)

Here is my code for the two classes. I am not sure what is happening here? The textfield is not updating the @Published 'cityInput' variable.

I am trying to have the user enter the name of their city and then use that variable to call a weather API for the city they entered. However when I print the variable (cityInput) or use it, it remains the default. It isn't updated

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()
    }
}

You're not calling back networkingManager.load() When you finish editing, nothing will change.. if you plan to show the forecast details in ForecastView() ? if you trying to do this you need to pass the it using @Binding var details or passing the networking manager like this:

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

struct ForecastView: View {
    @ObservedObject var manager: NetworkingManager

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM