【发布时间】:2020-06-29 07:47:39
【问题描述】:
我是一名新手程序员,正在尝试创建单视图天气应用程序。我的目标是编辑 dateLbl1 在 WeeklyWeatherViewController 中创建的 HomeViewController em>。
我的代码是这样写的:
let WeeklyWeatherView = WeeklyWeatherViewController()
...
WeeklyWeatherView.dateLbl1.text = nextDayShort[0].uppercased()
但是标签的值是“nil”。
致命错误:在隐式展开可选值时意外发现 nil
(nextDayShort 不为零,我将 UILabel 连接到 Storyboard)
在网上搜索我的问题并尝试将 ViewController 称为:
var swipePage: WeeklyWeatherViewController = UIStoryboard(name: "main", bundle: nil).instantiateViewControllerWithIdentifier("MyStoryboard")
我收到此错误:
线程 1:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)
我阅读了有关在视图控制器之间传递数据的信息,但根本无法在我的代码中使用它们。我该如何解决这个问题? 感谢您的帮助!
HomeViewController.swift
import UIKit
import Foundation
import CoreLocation
let DateView = DateViewController()
let WeatherView = WeatherViewController()
let WeeklyWeatherView = WeeklyWeatherViewController()
var currentHour : String?
var currentDay: String?
var nextDayShort = [String]()
var listCount = 0
class HomeViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet var backgroudView: UIView!
@IBOutlet weak var daysView: UIView!
@IBOutlet weak var timeView: UIView!
@IBOutlet weak var splashImage: UIImageView!
@IBOutlet weak var weatherView: UIView!
@IBOutlet weak var middleView: UIView!
@IBOutlet weak var rightView: UIView!
@IBOutlet weak var leftView: UIView!
@IBOutlet weak var middleHourBGView: UIView!
var locationManager: CLLocationManager?
override func viewDidAppear(_ animated: Bool) {
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestAlwaysAuthorization()
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.startUpdatingLocation()
if CLLocationManager.locationServicesEnabled() {
switch CLLocationManager.authorizationStatus() {
case .restricted, .denied:
let alert = UIAlertController(title: "Locations servies are disabled!", message: "Please go to settings and allow location services or the application can't fetch weather data.", preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
return
}
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
}
}
alert.addAction(settingsAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
case .authorizedAlways, .authorizedWhenInUse:
print("Access")
@unknown default:
break
}
} else {
print("Location services are not enabled")
}
}
override func viewDidLoad() {
super.viewDidLoad()
styleUI()
}
private func styleUI(){
daysView.layer.cornerRadius = 10
daysView.layer.shadowOpacity = 0.5
daysView.layer.shadowOffset = .zero
daysView.layer.shadowRadius = 10
middleView.layer.cornerRadius = 25
middleHourBGView.layer.cornerRadius = 10
let now = Date()
let formatter = DateFormatter()
let hour = Calendar.current.component(.hour, from: Date())
formatter.timeZone = TimeZone.current
formatter.dateFormat = "MMMM dd,YYYY EEEE"
let dateString = formatter.string(from: now)
DateView.dateLbl?.text = dateString
currentHour = String(hour)
let formatter2 = DateFormatter()
for n in 1..<6 {
var dayComponent = DateComponents()
dayComponent.day = n
let theCalendar = Calendar.current
let nextDate = theCalendar.date(byAdding: dayComponent, to: Date())
formatter2.dateFormat = "EE"
let nextDaySh = formatter2.string(from: nextDate! as Date)
nextDayShort.append(nextDaySh)
}
DispatchQueue.main.async {
WeeklyWeatherView.dateLbl1.text = nextDayShort[0].uppercased()
WeeklyWeatherView.dateLbl2.text = nextDayShort[1].uppercased()
WeeklyWeatherView.dateLbl3.text = nextDayShort[2].uppercased()
WeeklyWeatherView.dateLbl4.text = nextDayShort[3].uppercased()
WeeklyWeatherView.dateLbl5.text = nextDayShort[4].uppercased()
}
if (hour > 5 && hour < 21) {
backgroudView.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
timeView.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
daysView.layer.shadowColor = #colorLiteral(red: 0.3333333433, green: 0.3333333433, blue: 0.3333333433, alpha: 1)
} else {
backgroudView.backgroundColor = #colorLiteral(red: 0.0862745098, green: 0.09411764706, blue: 0.3058823529, alpha: 1)
timeView.backgroundColor = #colorLiteral(red: 0.0862745098, green: 0.09411764706, blue: 0.3058823529, alpha: 1)
DateView.cityLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
DateView.dateLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
DateView.tempLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
daysView.layer.shadowColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
WeatherView.leftHourLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
WeatherView.leftTempLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
WeatherView.rightHourLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
WeatherView.rightTempLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
WeatherView.middleTempLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location:CLLocationCoordinate2D = manager.location!.coordinate
weather.getWeather(lat: location.latitude, lon: location.longitude) { weather in
DispatchQueue.main.async {
DateView.cityLbl.text = weather.city.name
DateView.tempLbl.text = "\(Int(round(weather.list[0].main.temp)) - 273)°"
WeeklyWeatherView.tempLbl1.text = "\(Int(round(weather.list[1].main.temp)) - 273)°"
WeeklyWeatherView.tempLbl2.text = "\(Int(round(weather.list[2].main.temp)) - 273)°"
WeeklyWeatherView.tempLbl3.text = "\(Int(round(weather.list[3].main.temp)) - 273)°"
WeeklyWeatherView.tempLbl4.text = "\(Int(round(weather.list[4].main.temp)) - 273)°"
WeeklyWeatherView.tempLbl5.text = "\(Int(round(weather.list[5].main.temp)) - 273)°"
self.splashImage.isHidden = true
}
}
}
}
WeeklyWeatherViewController.swift
import UIKit
import Foundation
let storyBoardEdit = StoryboardEditor()
let weather = WeatherAPI()
class WeeklyWeatherViewController: UIView {
@IBOutlet weak var dateLbl1: UILabel!
@IBOutlet weak var dateLbl2: UILabel!
@IBOutlet weak var dateLbl3: UILabel!
@IBOutlet weak var dateLbl4: UILabel!
@IBOutlet weak var dateLbl5: UILabel!
@IBOutlet weak var tempLbl1: UILabel!
@IBOutlet weak var tempLbl2: UILabel!
@IBOutlet weak var tempLbl3: UILabel!
@IBOutlet weak var tempLbl4: UILabel!
@IBOutlet weak var tempLbl5: UILabel!
@IBOutlet weak var weatherImg1: UIImageView!
@IBOutlet weak var weatherImg2: UIImageView!
@IBOutlet weak var weatherImg3: UIImageView!
@IBOutlet weak var weatherImg4: UIImageView!
@IBOutlet weak var weatherImg5: UIImageView!
func fillUI(){
dateLbl1.text = nil
var dayId = [String]()
for x in 1..<6 {
dayId.append("03d")
let dayIdInt = Int(dayId[x-1])!
let imageIDName = storyBoardEdit.editWeatherIcons(dayIDInt: dayIdInt)
switch x {
case 1:
DispatchQueue.main.async {
self.weatherImg1.image = UIImage(named: imageIDName)
}
case 2:
DispatchQueue.main.async {
self.weatherImg2.image = UIImage(named: imageIDName)
}
case 3:
DispatchQueue.main.async {
self.weatherImg3.image = UIImage(named: imageIDName)
}
case 4:
DispatchQueue.main.async {
self.weatherImg4.image = UIImage(named: imageIDName)
}
case 5:
DispatchQueue.main.async {
self.weatherImg5.image = UIImage(named: imageIDName)
}
default:
break
}
}
}
}
【问题讨论】:
-
请分享您的完整代码...
-
@jawadAli 已添加,谢谢。
-
不要将视图控制器声明为@IBOutlet
-
@Stefan 感谢您的额外建议,我更新了我的代码并发布了。
-
如果它在 Storyboard 中,您确实应该使用第二种方法。但是,我认为问题在于视图未加载,因此插座也没有加载。你不是在展示视图控制器吗?那你为什么要设置它的标签值呢?你已经介绍了一个吗?如果是这样,您创建了一个全新的对象,而不是已经存在的对象。