无法从另一个视图控制器更改 UILabel.text,UILabel 获取零值



我是一个新手程序员,正在尝试创建一个单一视图天气应用程序。我的目标是从HomeViewController编辑在WeeklyWeatherViewController中创建的dateLbl1

我像这样写我的代码:

let WeeklyWeatherView = WeeklyWeatherViewController()
...
WeeklyWeatherView.dateLbl1.text = nextDayShort[0].uppercased()

但是标签得到"零"值。

致命错误:隐式解包可选值时意外发现 nil

(nextDayShort 不是零,我将 UILabel 连接到故事板(

在网络上搜索我的问题,并尝试调用ViewController为:

var swipePage: WeeklyWeatherViewController = UIStoryboard(name: "main", bundle: nil).instantiateViewControllerWithIdentifier("MyStoryboard")

我收到此错误:

线程 1:EXC_BAD_INSTRUCTION(代码 = EXC_I386_INVOP,子代码 = 0x0(

我读过有关在视图控制器之间传递数据的信息,但根本无法在我的代码中使用它们。如何解决此问题? 感谢您的任何帮助!

主视图控制器.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
}
}
}
}

是否更改:

  • 在情节提要(或 Xib(中,将weatherView的类更新为WeeklyWeatherViewController并重置出口。你应该这样得到它:
@IBOutlet weak var weatherView: WeeklyWeatherViewController!
  • 删除以下行:
let WeeklyWeatherView = WeeklyWeatherViewController()
  • 在您的styleUI()方法中,使用以下方法替换使用WeeklyWeatherView的行:
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()
}

在你的 locationManager(( 函数中,使用WeeklyWeatherView替换行:

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)º"

看到我在这两种情况下都使用新创建的插座,对吧?

问题是你初始化WeeklyWeatherViewController的方式

let WeeklyWeatherView = WeeklyWeatherViewController()

此视图具有从中创建连接的关联 xib。现在,当您初始化WeeklyWeatherViewController类时,您的 xib 视图尚未初始化。

您需要在WeeklyWeatherViewControllerinit方法中加载 nib 文件。

class WeeklyWeatherViewController: UIView {
override init(frame: CGRect) {
super.init(frame: frame)

let contentView = Bundle.main.loadNibNamed("your_nib", owner: self, options: nil)?.first as? UIView
addSubview(contentView!)

// set constraints for contentView.
}
convenience init() {
let defaultFrame = //provide your default frame
self.init(frame: defaultFrame)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

所以问题是当你有一个关联的xib文件时,简而言之,当你从外部提供你的视图时,你需要初始化该外部视图并将其附加到你的类。这样,您的视图仍将保留内存,您可以访问所有连接的IBOutlet

最新更新