Swift:无法在实例化视图控制器中更改属性

时间:2018-12-10 16:27:52

标签: ios swift

我是Swift的新手,所以接下来可能是一个非常基本的问题。另外,这是我在stackoverflow.com上的第一个!

在实例化的视图控制器中设置UILabel的文本属性时,出现“线程1:致命错误:在展开可选值时意外发现nil”。

我正在制作一个简单的应用程序,以显示我在家中拥有的药物清单及其有效期。表格视图控制器显示了一个名为medArray的数组中的药物列表,当点击每个药物时,我希望它加载带有一些更多详细信息的详细信息屏幕。

我使用IB设置了DetailView控制器,并创建了3个UILabel的插座连接:

//  DetailView.swift
//  HomeMed
//
//  Created by Joao Boavida on 10/12/2018.
//  Copyright © 2018 Joao Boavida. All rights reserved.
//

import UIKit

class DetailView: UIViewController {

    @IBOutlet var nameLbl: UILabel!
    @IBOutlet var subtextLbl: UILabel!
    @IBOutlet var expdateLbl: UILabel!

}

我认为连接成功,因为左侧装订线上的点是固定的。点击表格视图单元格时,我确实得到了错误,该代码调用以下代码:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let medicine = medArray[indexPath.row]

    if let vc = storyboard?.instantiateViewController(withIdentifier: "DetailView") as? DetailView {

        vc.nameLbl.text = medicine.name

        if let subtext = medicine.subtext {
            vc.subtextLbl.text = subtext
        } else {
            vc.subtextLbl.text = ""
        }

        let ISOdateFormatter = ISO8601DateFormatter()
        ISOdateFormatter.formatOptions = [.withMonth, .withYear, .withDashSeparatorInDate]

        vc.expdateLbl.text = "Exp: \(ISOdateFormatter.string(from: medicine.expiry))"

        navigationController?.pushViewController(vc, animated: true)

    }

}

当我尝试访问vc.nameLbl.text时,我立即收到错误消息,由于未知原因,该消息为nil。 vc.expdateLbl和vc.subtextLbl也为零。

“ vc”视图控制器似乎已正确实例化,因为如果我省略了配置代码并在创建它后立即将其推送,尽管我在IB中设置了标签中的初始文本,但它显示得很好。只有当我尝试更改这些标签时,它才会崩溃。

我尝试制作和重新制作插座连接没有成功。有人可以帮忙解决此问题吗?

非常感谢您!

2 个答案:

答案 0 :(得分:0)

您要在此处设置VC的插座,对吧?

    vc.nameLbl.text = medicine.name <---

    if let subtext = medicine.subtext {
        vc.subtextLbl.text = subtext <---
    } else {
        vc.subtextLbl.text = "" <---
    }
    ...
    vc.expdateLbl.text = "Exp: \(ISOdateFormatter.string(from: medicine.expiry))" <---

运行上述代码时,出口nameLblsubtextLblexpdateLbl都为零。它们尚未设置在该时间点。

调用viewDidLoad时已经设置了出口 。因此,您可以做的是在DetailView中添加三个属性:

var name: String!
var subtext: String!
var expdate: String!

您无需设置插座,而是设置了以上三个属性:

    vc.name = medicine.name <---

    if let subtext = medicine.subtext {
        vc.subtext = subtext <---
    } else {
        vc.subtext = "" <---
    }
    ...
    vc.expdat = "Exp: \(ISOdateFormatter.string(from: medicine.expiry))" <---

然后,在DetailView中,将属性分配给text中标签的viewDidLoad

override func viewDidLoad() {
    nameLbl.text = name
    subtextLbl.text = subtext
    expdateLbl.text = expdate
}

答案 1 :(得分:-2)

它崩溃是因为您正在尝试加载UILabel之前对其进行访问。因此,您应该致电vc.loadViewIfNeeded()。这将加载所有UIViewController视图。