加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift / iOS:加载视图控制器后IBOutlet为零

发布时间:2020-12-14 18:55:29 所属栏目:百科 来源:网络整理
导读:我正在构建一个应用程序(在XCode 8.2.1中),其中一些对象显示在2D板上,当用户点击其中一个对象时,应该将某些信息显示为样式模态信息框.我的设计是将信息写在一个单独的视图控制器中,我会在需要时显示. 我为第二个视图控制器设计了一个基本存根,并在界面构建器
我正在构建一个应用程序(在XCode 8.2.1中),其中一些对象显示在2D板上,当用户点击其中一个对象时,应该将某些信息显示为样式模态信息框.我的设计是将信息写在一个单独的视图控制器中,我会在需要时显示.

我为第二个视图控制器设计了一个基本存根,并在界面构建器中为它添加了一个标签.然后我将此标签ctrl链接到我的自定义VC类:

class InfoViewController: UIViewController {
    @IBOutlet weak var info: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    func displayInfo() {
        info.attributedText = NSAttributedString(string: "abc")
    }
}

但是,当我测试我的应用程序并点击该对象时,即使在我的自定义VC类的viewDidLoad()方法中,info字段也是nil.我正在显示我的VC的方式如下:

let infoViewController = InfoViewController()
infoViewController.modalPresentationStyle = .overCurrentContext
self.present(infoViewController,animated: true,completion: nil)
infoViewController.displayInfo()

(注意:最后我将只有一个InfoViewController实例,但这仅用于测试.我不希望全局实例会有任何区别吗?)

正如我所说,无论是在viewDidLoad()方法内还是在displayInfo()方法中,info始终为nil,因此设置其attributionString属性会使应用程序崩溃.认为本方法可能是异步调用的,我试过从viewDidLoad()内部调用displayInfo(),但这没有任何区别.

任何人都可以告诉我我忘记了什么会让我的IBOutlet正确初始化吗?

谢谢!

大卫

解决方法

问题是对InfoViewController()的引用,它独立于任何故事板场景实例化视图控制器.你想使用 instantiateViewController

let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController,animated: true) {
    infoViewController.displayInfo()
}

几个笔记:

>这假定(a)你已经在故事板中给出了一个“故事板id”; (b)您已将该场景的基类设置为InfoViewController.
>注意,我在当前的完成处理程序中调用了displayInfo,因为在场景出现并且连接了插座之前你可能不希望调用它.

或者,您可以在实例化后立即更新InfoViewController的非出口属性,然后使其viewDidLoad获取这些属性并更新出口,例如:

class InfoViewController: UIViewController {
    var info: String!
    @IBOutlet weak var infoLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        infoLabel.attributedText = NSAttributedString(string: info)
    }
}

注意,我将@IBOutlet名称更改为infoLabel并添加了名为info的String属性.这往往是惯例,出口带有一些后缀表示控件的类型,而模型对象,如String属性,没有后缀. (您只需要确保在IB中的连接检查器中删除旧的插座,这样您就不会遇到这些属性名称更改的问题.)

无论如何,你可以这样做:

let infoViewController = storyboard?.instantiateViewController(withIdentifier: "Info") as! InfoViewController
infoViewController.info = "abc"
infoViewController.modalPresentationStyle = .overCurrentContext
present(infoViewController,completion: nil)

关键点是在实例化之后不要尝试立即更新场景的出口,但要确保在调用viewDidLoad之前将其延迟.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读