在segue之间推送信息是行不通的

时间:2018-03-07 17:35:57

标签: swift uilabel uitextview segue

我有意见A和B.

视图A有两个不同的段来查看B和我的prepareForSegue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        let nextView = segue.destination as! LabelWithTextView
        nextView.HeaderLabel = UILabel()
        nextView.TextToDisplay = UITextView()

        if segue.identifier == "segue_to_tc"
        {

            nextView.HeaderLabel.text = "Terms and Conditions"
            nextView.TextToDisplay.text = "Terms and Conditions agreement will be displayed here once available."
        }
        else if segue.identifier == "segue_to_p"
        {
            nextView.HeaderLabel.text = "Privacy Policy"
            nextView.TextToDisplay.text = "Privacy Policy agreement will be displayed here once available."
        }
    }

和视图B:

class LabelWithTextView: UIViewController
{
    var HeaderLabel: UILabel!

    var TextToDisplay: UITextView!


    override func viewDidLoad()
    {
        super.viewDidLoad()

        self.navigationController?.setNavigationBarHidden(false, animated: true)
        TextToDisplay.isEditable = false
        self.view.bringSubview(toFront: HeaderLabel)
        self.view.bringSubview(toFront: TextToDisplay)
    }
}

但是当我执行segue时,没有显示任何信息:

View B after segue

在上一次迭代中,我的故事板中有两个带有插座的对象,它们也没有改变。如果我在PrepareForSegue中取出HeaderLabel和TextToDisplay实例,它会崩溃,因为它们是零。

有没有办法删除PrepareForSegue中的实例化? 如何正确传递信息?

2 个答案:

答案 0 :(得分:1)

它清楚地表明您有一个导航控制器作为您的segue的目的地,所以您可以做的是在 prepareForSegue 将目的地转换为 UINavigationController ,然后使用其 topViewController 作为您的目的地

ngOnInit

答案 1 :(得分:1)

您在问题中包含的代码无效,因为您从未在HeaderLabel中添加TextToDisplayself.view作为LabelWithTextView的子视图。

您的“上一次迭代”,其中HeaderLabelTextToDisplay位于故事板中,可能因为您尝试访问HeaderLabelTextToDisplay而无法正常工作在它们被装载之前。当UIKit执行segue时,它会实例化目标视图控制器并在之前发送prepareForSegue:sender:消息加载目标视图控制器的视图。

源视图控制器的工作通常不是直接访问目标视图控制器的视图层次结构。

解决此问题的一种常见方法是引入模型对象并将其传递到目标。例如,我们可以创建一个struct来保存政策详细信息:

struct PolicyModel {
    var title: String
    var body: String
}

然后我们可以为目标视图控制器提供此类型的属性,并在重新加载后使用该属性配置视图:

class PolicyViewController: UIViewController {

    var policy = PolicyModel(title: "", body: "") {
        didSet { updateViews() }
    }

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var bodyView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()
        updateViews()
    }

    private func updateViews() {
        guard isViewLoaded else { return }
        titleLabel.text = policy.title
        bodyView.text = policy.body
    }
}

最后,在segue源代码中,我们可以根据segue标识符设置目标' policy

class SourceViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        switch (segue.identifier ?? "", segue.destination) {
        case ("TermsAndConditions", let destination as PolicyViewController):
            destination.policy = PolicyModel(title: "Terms and Conditions", body: "Blah blah blah")
        case ("Privacy", let destination as PolicyViewController):
            destination.policy = PolicyModel(title: "Privacy Policy", body: "Blah blah blah")
        default: super.prepare(for: segue, sender: sender)
        }
    }

}