我一直在浏览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而不是使用属性,或者有没有方法可以清理掉它可以接受吗?
答案 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
}
}
这样,我们不将布尔值存储在任何一个视图控制器中,而是存储在用户默认值中,并使事情变得更加简单。
我认为这是一种更清洁的解决方案,但其他人可能会提出更好的建议。