【问题标题】:How to change the value of a var with a TextField SwiftUI如何使用 TextField SwiftUI 更改 var 的值
【发布时间】:2022-11-15 13:23:12
【问题描述】:

我试图进行天气 api 调用,api 调用需要有一个位置。我传递它的位置是一个变量。但是现在我想用我在上面写的 TextField 所具有的值来更改位置值。为了安全起见,我将 apiKey 缩短了。还有更多代码,但不相关。 我只需要知道如何使用 cityTextField 结构上的 TextField 更改 WeatherClass 上的城市变量。

谢谢。

class WeatherClass: ObservableObject {
    @Published var weatherAddress: String = ""
    @Published var weatherDays: [WeatherDays] = []
    var city: String = ""
  
    func fetch() {
        let location = city
        let apiKey = "AP8LUYMSTHZ"
        
        let url = URL(string: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/\(location)?key=\(apiKey)")!
            URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
                
            if let weather = try? JSONDecoder().decode(WeatherData.self, from: data) {
                DispatchQueue.main.async {
                    
                    self.weatherAddress = weather.resolvedAddress
                    self.weatherDays = weather.days
                }
            } else {
                print("City?")
            }
        }.resume()
    }//----------------------------------- End of fetch()
}
struct WeatherData: Decodable {
    let resolvedAddress: String
    let days: [WeatherDays]
}
struct WeatherDays: Hashable, Decodable {
    let datetime: String
    let tempmax: Double
    let tempmin: Double
    let description: String
}

struct cityTextField: View {
    
    @State var city: String = ""
    
    var body: some View {
       
            TextField("Search city", text: $city).frame(height:30).multilineTextAlignment(.center).background().cornerRadius(25).padding(.horizontal)
    } 
}

我已经看过很多类似的教程,但没有一个对我有真正的帮助。

【问题讨论】:

  • 您是否尝试过在WeatherClass 中的city 变量上使用@Published,而不是将其绑定到视图中的@State 变量?
  • @synapticloop 我还没有,这里已经很晚了所以我明天要试试。无论如何感谢您的评论。我不知道这是否是回复您评论的正确方式,因为我是新来的哈哈。

标签: swift xcode macos swiftui


【解决方案1】:

尝试使用此方法对 func fetch(_ city: String){...} 获取你所在城市的天气 TextField使用.onSubmit{...}

struct ContentView: View {
    @StateObject var weatherModel = WeatherClass()
    
    var body: some View {
        VStack {
            cityTextField(weatherModel: weatherModel)
        }
    }
}

struct cityTextField: View {
    @ObservedObject var weatherModel: WeatherClass  // <-- here
    @State var city: String = ""
    
    var body: some View {
            TextField("Search city", text: $city)
            .frame(height:30)
            .multilineTextAlignment(.center)
            .background()
            .cornerRadius(25)
            .padding(.horizontal)
            .onSubmit {
                weatherModel.fetch(city)  // <-- here
            }
    }
}

class WeatherClass: ObservableObject {
    @Published var weatherAddress: String = ""
    @Published var weatherDays: [WeatherDays] = []

    func fetch(_ city: String) {  // <-- here
        let apiKey = "AP8LUYMSTHZ"
        
        // -- here
        let url = URL(string: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/(city)?key=(apiKey)")!
        
            URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            if let weather = try? JSONDecoder().decode(WeatherData.self, from: data) {
                DispatchQueue.main.async {
                    self.weatherAddress = weather.resolvedAddress
                    self.weatherDays = weather.days
                }
            } else {
                print("City?")
            }
        }.resume()
    }
}

或者,正如 synapticloop 所建议的,您可以使用这种方法:

struct cityTextField: View {
    @ObservedObject var weatherModel: WeatherClass  // <-- here

    var body: some View {
        TextField("Search city", text: $weatherModel.city) // <-- here
            .frame(height:30)
            .multilineTextAlignment(.center)
            .background()
            .cornerRadius(25)
            .padding(.horizontal)
            .onSubmit {
                weatherModel.fetch()  // <-- here
            }
    }
}

class WeatherClass: ObservableObject {
    @Published var weatherAddress: String = ""
    @Published var weatherDays: [WeatherDays] = []
    @Published var city: String = "" // <-- here

    func fetch() {
        let apiKey = "AP8LUYMSTHZ"
        
        // -- here
        let url = URL(string: "https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/(city)?key=(apiKey)")!
        
            URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            if let weather = try? JSONDecoder().decode(WeatherData.self, from: data) {
                DispatchQueue.main.async {
                    self.weatherAddress = weather.resolvedAddress
                    self.weatherDays = weather.days
                }
            } else {
                print("City?")
            }
        }.resume()
    }
}

【讨论】:

  • 抱歉,我不知道这是否是重播您的正确方式,也不知道如何标记您,但感谢您的留言,我明天会尝试您的建议。
  • 单击答案附近的刻度线,它变成绿色,谢谢。
猜你喜欢
  • 2021-03-17
  • 2023-04-10
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
相关资源
最近更新 更多