为啥我不能访问这个数组 ForEach 循环中的数据? SwiftUI
Posted
技术标签:
【中文标题】为啥我不能访问这个数组 ForEach 循环中的数据? SwiftUI【英文标题】:Why cannot I not access the data in this array ForEach loop? SwiftUI为什么我不能访问这个数组 ForEach 循环中的数据? SwiftUI 【发布时间】:2019-11-30 15:39:13 【问题描述】:我在这个问题上遇到了一些困难。由于某种原因,ForEach 循环不允许我使用“天气”对象中的数据。我之前已经这样做了,我可以放置 weather.main.rTemp 并从对象中获取值,但现在我收到一个错误,说这不存在,但是没有任何改变?它在 Xcode 自动填充中建议的唯一选项是 weather.self (这也不起作用或有帮助)
我迷路了,请帮帮我。
我的主要观点:
import SwiftUI
struct MainForecastView: View
@ObservedObject var networkingManager: NetworkingManager
var body: some View
VStack
// Text("Weather Forecast")
// .font(.headline)
// .padding(.bottom, 25.0)
HStack(alignment: .bottom)
VStack(alignment: .leading)
Text("Today")
.font(.largeTitle)
.fontWeight(.medium)
Text(self.getDateToday())
.font(.subheadline)
Image(systemName: "sun.min.fill")
.font(.system(size: 36))
.foregroundColor(Color.yellow)
.padding()
Spacer()
VStack
Text("12°")
.font(.system(size:48))
.fontWeight(.medium)
.multilineTextAlignment(.trailing)
Text("Sydney, AU")
.multilineTextAlignment(.trailing)
.padding()
HStack
Text("Upcoming Forecast")
.font(.headline)
.multilineTextAlignment(.leading)
.padding(.top)
Spacer()
.padding(.leading, 10.0)
ScrollView(.horizontal, content:
HStack(spacing: 5)
ForEach(networkingManager.weatherList, id: \.dt) weather in
CardView(forecastTime: "12PM", forecastTemp: self.networkingManager.weatherList[0].main.rTemp)
.padding(.vertical)
)
VStack
HStack
Text("Chance of Showers")
.font(.headline)
Spacer()
.padding(.leading, 10.0)
HStack
Image(systemName: "cloud.rain.fill")
.font(.system(size: 28))
Text("Low Chance")
.font(.title)
.padding()
.padding(.leading, 10.0)
Spacer()
.onAppear()
self.networkingManager.load()
.blur(radius: 0)
.padding()
func getDateToday() -> String
let df = DateFormatter()
df.dateFormat = "MMMM dd"
let dateToday = df.string(from: Date())
return dateToday
struct MainForecastView_Previews: PreviewProvider
static var previews: some View
MainForecastView(networkingManager: NetworkingManager())
然后到我的网络管理器课程
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 = "ced81d2f91438e7897c4443c4567c205"
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/forecast?q=\(inputCity)&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()
最后是来自 API 的数据模型结构
import Foundation
struct WeatherAPIResponse: Decodable
var list: [WeatherInfoList]
var city: CityInformation
struct CityInformation: Decodable
var name: String
var country: String
struct WeatherInfoList: Decodable
let formatter = DateFormatter()
var dt: Int
var main: WeatherMain
var dtTxt: String
var date: String
formatter.dateFormat = "EEE hh:mm a"
let cDate = Date.init(timeIntervalSince1970: TimeInterval(dt))
return formatter.string(from: cDate)
enum CodingKeys: String, CodingKey
case dt
case main
case dtTxt = "dt_txt"
struct WeatherMain: Decodable
let temp, tempMin, tempMax: Double
let pressure, seaLevel, grndLevel, humidity: Int
let tempKf: Double
var rTemp: Int
return Int(temp)
var rTempMax: Int
return Int(tempMax)
var rTempMin: Int
return Int(tempMin)
enum CodingKeys: String, CodingKey
case temp
case tempMin = "temp_min"
case tempMax = "temp_max"
case pressure
case seaLevel = "sea_level"
case grndLevel = "grnd_level"
case humidity
case tempKf = "temp_kf"
【问题讨论】:
【参考方案1】:我刚刚尝试了您的代码(我不得不稍微更改它,但它是可编译的)。
试试这个:
很遗憾,您没有向我们展示您的 cardView 实现...也许问题出在哪里?
import SwiftUI
import Foundation
import Combine
struct ContentView: View
@ObservedObject var networkingManager: NetworkingManager
var body: some View
VStack
// Text("Weather Forecast")
// .font(.headline)
// .padding(.bottom, 25.0)
HStack(alignment: .bottom)
VStack(alignment: .leading)
Text("Today")
.font(.largeTitle)
.fontWeight(.medium)
Text(self.getDateToday())
.font(.subheadline)
Image(systemName: "sun.min.fill")
.font(.system(size: 36))
.foregroundColor(Color.yellow)
.padding()
Spacer()
VStack
Text("12°")
.font(.system(size:48))
.fontWeight(.medium)
.multilineTextAlignment(.trailing)
Text("Sydney, AU")
.multilineTextAlignment(.trailing)
.padding()
HStack
Text("Upcoming Forecast")
.font(.headline)
.multilineTextAlignment(.leading)
.padding(.top)
Spacer()
.padding(.leading, 10.0)
ScrollView(.horizontal, content:
HStack(spacing: 5)
ForEach(networkingManager.weatherList, id: \.dt) weather in
// CardView(forecastTime: "12PM", forecastTemp: self.networkingManager.weatherList[0].main.rTemp)
Text(weather.date)
.padding(.vertical)
)
VStack
HStack
Text("Chance of Showers")
.font(.headline)
Spacer()
.padding(.leading, 10.0)
HStack
Image(systemName: "cloud.rain.fill")
.font(.system(size: 28))
Text("Low Chance")
.font(.title)
.padding()
.padding(.leading, 10.0)
Spacer()
.onAppear()
self.networkingManager.load()
.blur(radius: 0)
.padding()
func getDateToday() -> String
let df = DateFormatter()
df.dateFormat = "MMMM dd"
let dateToday = df.string(from: Date())
return dateToday
struct MainForecastView_Previews: PreviewProvider
static var previews: some View
ContentView(networkingManager: NetworkingManager())
class NetworkingManager : ObservableObject
@Published var inputCity = "Sydney"
@Published var weatherList = [WeatherInfoList]()
var weatherCity = CityInformation(name: "Sydney", country: "AU")
func load()
let apiKey = "ced81d2f91438e7897c4443c4567c205"
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/forecast?q=\(inputCity)&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()
struct WeatherAPIResponse: Decodable
var list: [WeatherInfoList]
var city: CityInformation
struct CityInformation: Decodable
var name: String
var country: String
struct WeatherInfoList: Decodable
let formatter = DateFormatter()
var dt: Int
var main: WeatherMain
var dtTxt: String
var date: String
formatter.dateFormat = "EEE hh:mm a"
let cDate = Date.init(timeIntervalSince1970: TimeInterval(dt))
return formatter.string(from: cDate)
enum CodingKeys: String, CodingKey
case dt
case main
case dtTxt = "dt_txt"
struct WeatherMain: Decodable
let temp, tempMin, tempMax: Double
let pressure, seaLevel, grndLevel, humidity: Int
let tempKf: Double
var rTemp: Int
return Int(temp)
var rTempMax: Int
return Int(tempMax)
var rTempMin: Int
return Int(tempMin)
enum CodingKeys: String, CodingKey
case temp
case tempMin = "temp_min"
case tempMax = "temp_max"
case pressure
case seaLevel = "sea_level"
case grndLevel = "grnd_level"
case humidity
case tempKf = "temp_kf"
【讨论】:
以上是关于为啥我不能访问这个数组 ForEach 循环中的数据? SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章