【问题标题】:Swift Text Label Nil Even With Default ValueSwift 文本标签 Nil 即使使用默认值
【发布时间】:2016-02-29 04:50:52
【问题描述】:

这快把我逼疯了。正在调用函数updateTextView(),由打印语句验证,但它没有在我的视图控制器中设置标签,并且标签的打印语句返回 nil,即使它设置了默认值,当应用程序已加载。更令人困惑的是,我设置了一个测试按钮来单独调用这个函数,当我用test()调用它时,标签会正确更新。

class GoalDetailViewController: UIViewController, TextDelegate {

    @IBAction func test(sender: AnyObject) {
        updateTextView()
    }

    func updateTextView() {
        print(goalSummaryTextBox?.text)
        print("delegate called")
        self.goalSummaryTextBox?.text = GoalsData.summaryText
        print(goalSummaryTextBox?.text)
    }

    @IBOutlet weak var goalTitle: UILabel?
    @IBOutlet weak var goalCreationDate: UILabel?
    @IBOutlet weak var goalSummaryTextBox: UITextView?

    override func viewDidLoad() {
        super.viewDidLoad()

        goalSummaryTextBox?.text = GoalsData.summaryText
    }
}

updateTextView() 在弹出不同的视图控制器后通过委托方法被调用,如下所示:

class TextEditViewController: UIViewController {
    var textDelegate: TextDelegate?

    @IBOutlet weak var textView: UITextView?

    func configureView() {
        navigationItem.title = "Edit Description"
        navigationItem.setRightBarButtonItem((UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: "segue")), animated: true)
    }

    func segue() {
        textDelegate = GoalDetailViewController()

        if let text = textView?.text {    
            GoalsData.summaryText = text
        }

        textDelegate?.updateTextView()        
        self.navigationController?.popViewControllerAnimated(true)
    }
}

【问题讨论】:

  • 最后一句话可能是问题所在。
  • 你能详细说明一下吗?由于打印语句,我知道它调用函数。
  • 您能否发布与弹出的不同视图控制器相关的代码(并触发updateTextView() 调用)?可能是在后台队列上调用了updateTextView()。您是否也可以将print(GoalsData.summaryText) 添加到updateTextView() 以确保它确实不同?
  • @Mark ` func segue() { textDelegate = GoalDetailViewController() if let text = textView?.text {GoalsData.summaryText = text } textDelegate?.updateTextView() self.navigationController?.popViewControllerAnimated(true ) } summaryText 确实打印了正确的值。我尝试将分派中的标签更新移动到主队列的东西,但它没有影响结果
  • 您是否有理由不在 IBOutlets 中使用隐式展开的选项?

标签: swift label viewcontroller


【解决方案1】:

导致问题的行在下面的TextEditViewController 中:

textDelegate = GoalDetailViewController()

这一行的作用是创建GoalDetailViewController 的新实例,并将其设置为TextEditViewController 的委托。但是,您想要的是 GoalDetailViewController 的原始实例作为委托。这就是为什么您在弹出TextEditViewController 时看到日志的原因,因为它正在执行另一个实例(它不是视图层次结构的一部分)。它还解释了为什么在委托调用中单步执行 updateTextView() 时所有 IBOutlets 都为零,并且您添加的按钮会正确更新文本。

解决方法是在prepareForSegue方法中进行委托连接:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if let destination = segue.destinationViewController as? TextEditViewController {
        destination.textDelegate = self
    }
}

将上述代码添加到您的GoalDetailViewController。

编辑:

以下代码将确保以后不会发生此问题。将委托的定义更改为:

weak var textDelegate: TextDelegate?

并将您的协议更改为:

protocol TextDelegate: class {
    func updateTextView()
}

【讨论】:

  • 谢谢。在旁注中,这是我一直在努力解决的问题:与视图控制器的特定实例进行通信。 prepareForSegue 是与特定实例交谈的唯一方法吗?非常感谢你,这很好用
  • 使用情节提要时,它是将两个视图控制器链接在一起的最简单方法之一。
  • 如果这解决了您的问题,请将其标记为正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 2015-03-02
  • 1970-01-01
  • 2017-12-05
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多