Swift 即使使用默认值,文本标签也为零

Swift Text Label Nil Even With Default Value

这让我发疯。函数 updateTextView() 正在被调用,由 print 语句验证,但它没有在我的视图控制器中设置标签,标签的 print 语句返回 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)
    }
}

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

textDelegate = GoalDetailViewController()

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

解决方法是在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()
}