在Swift中重用视图控制器而没有被黑的属性

时间:2019-02-16 09:59:46

标签: swift

我一直在浏览Coordinator tutorial,它提出了我过去编写的代码的问题。

就是说,当重用视图控制器时,我使用了一个属性来显示不同的元素,具体取决于用户来自哪个视图控制器。在上面的教程中,这被描述为黑客。

例如,我使用以下命令选择了labelviewcontroller

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "label" {
        let vc = segue.destination as! LabelViewController
        vc.originalVC = self
    }
}

然后在labelViewController上具有一个属性

var originalVC: ViewController?

然后我通过以下方法更改viewDidLoad()中的项目

override func viewDidLoad() {
    super.viewDidLoad()

    if originalVC != nil {
        label.text = "came direct"
        imageView.isHidden = true
    }
    else {
        label.text = "button"
        imageView.isHidden = false
    }
}

我在这里有一个可行的示例项目:https://github.com/stevencurtis/ReusibilityIssues

现在,我知道答案可能是使用Coordinator教程的,但是是否可以使用其他任何方法来简单地在两种不同情况下重用viewController而不是使用属性,或者有没有方法可以清理掉它可以接受吗?

3 个答案:

答案 0 :(得分:0)

  

但是我还有其他方法可以用于在两种不同情况下简单地重用viewController

如果您描述的“两种不同的情况”非常不同(我的意思是“需要运行非常不同的代码行”),那么您应该创建两个不同的视图控制器类,因为否则将违反Single Responsibility Principle

如果您的“两种不同情况”是不同的,但也很相关,那么您就可以将VC需要知道的所有信息作为属性。您当然不需要整个ViewController

例如,如果您的LabelViewController仅在由ViewControllerFoo出现时才会显示“ foo”按钮。

您可以在showFooButton中添加LabelViewController属性:

var showFooButton = false

override func viewDidLoad() {
    fooButton.isHidden = !showFooButton
}

然后在ViewControllerFoo.prepareForSegue中输入:

if segue.identifier == "label" {
    let vc = segue.destination as! LabelViewController
    vc.showFooButton = true
}

我不会称其为hack。这是this post中描述的推荐方式,他们没有称其为hack。

答案 1 :(得分:0)

只要将父类型推入这样的导航控制器中,就可以通过检查父类型而无需传递originalVC来做到这一点:

if let p = parent {
        if p.isKind(of: OriginalViewController.self){
            //it pushed in navigation controller stack after OriginalViewController
        }
    }

答案 2 :(得分:-1)

我还没有尝试过Coordinator Pattern,所以我无法对此发表评论。 如果您正在寻找其他方法,我认为使用UserDefaults可能是更好的解决方案。

例如,假设您在按下按钮时对labelViewController执行了segue:

 @IBAction func buttonPressed(_ sender: Any) {
    userDefaults.set(true, forKey: "seguedHere")
    performSegue(withIdentifier: "segueToLabelVC", sender: self)
}

然后在labelViewController中:

override func viewDidLoad() {
super.viewDidLoad()

if userDefaults.bool(forKey: "seguedHere") == false {
    label.text = "came direct"
    imageView.isHidden = true
}
else {
    label.text = "button"
    imageView.isHidden = false
 }
}

这样,我们不将布尔值存储在任何一个视图控制器中,而是存储在用户默认值中,并使事情变得更加简单。

我认为这是一种更清洁的解决方案,但其他人可能会提出更好的建议。