是否有 ViewDidLoad 的替代方案?当 viewController 加载时,还有其他地方可以编写需要激活的代码吗?

Is there an alternative to ViewDidLoad? Any other place to write code which needs to be activated, when a viewController loads?

我有一个 viewController,其中包含三个文本字段。每个文本字段都连接到一个标签并使用 NSUser Default 以便当用户在文本字段中写入内容时,文本会使用一个键保存 - 并显示在分配给它的标签中。那很好用。

三个文本字段中的两个供用户编写 "a question" 和一个 "extra identifier"。如果用户不知道在其中写什么,在屏幕顶部有两个按钮指向两个不同的 tableViewControllers - 两个按钮都包含用户可以选择的带有 inspiration/options 的 tableView .我从每个实现了一个 segue,这样当用户点击 tableViewCell 时,此单元格中的文本将传递到 viewController1 中的正确文本字段 - 用户现在可以按保存并将此文本保存在NSUser Default 并让它显示在分配的标签中。

问题是这些 segues 当然使用 ViewDidLoad 来显示从灵感 tableViews 传递的文本。这意味着当您在保存后输入第二个 tableViewController 时,您从第一个选择 "question" ,然后 - 由于 viewDidLoad 方法 - 所有文本字段和标签将再次清除,只有你刚刚通过的内容里面显示...所以:

我可以使用 viewDidLoad 之外的其他方法将数据传递到 ViewController1 吗?

或者我可以向 viewDidLoad 方法添加一些代码,以便它在您每次输入 viewController 时停止 "resetting" 所有标签和文本字段吗?

还是我需要换一种完全不同的方式?

我希望这一切都有意义 - 抱歉解释太长了! :D

这是来自 viewController1 的相关代码:

var chosenQuestion:String = ""
var chosenIdentifier:String = ""

override func viewDidLoad() {
    super.viewDidLoad()
DiaryQuestionTextField.text = chosenQuestion
RandomIdentifierTextField.text = chosenIdentifier
}


@IBAction func WriteDiaryName() {

    let title = "You have now chosen you diary's name. \n \n Do you wish to save this name and continue? \n \n You can always change all the details."
    let alert =  UIAlertController(title: title, message: nil, preferredStyle: .alert)

    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))

    alert.addAction(UIAlertAction(title: "Save", style: .default, handler: { action in
        self.defaults.setValue(self.DiaryNameTextField.text, forKey: "DiaryNameKey")
        let NewDiaryName = self.defaults.string(forKey: "DiaryNameKey")
        self.DiaryNameLabel.text = NewDiaryName

    }))
        present(alert, animated: true, completion: nil)
    }

"WriteQuestion"和"WriteExtraIdentifier"当然有两种类似的方法。

这是来自两个 tableViewControllers 和 "inspiration" 之一的相关代码:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.destination is UpdatingIdentifiers {
        let vc = segue.destination as? UpdatingIdentifiers
        let selectedRowIndex = self.tableView.indexPathForSelectedRow
        let cell = self.tableView.cellForRow(at: selectedRowIndex!)
        let label = cell?.viewWithTag(420) as! UILabel
        vc?.chosenQuestion = label.text!
    }
}

谢谢!

对于这种情况,您可以简单地使用 closure 方法。

  1. ViewController2 中创建一个 closure 变量。
  2. 每当您从 ViewController1 显示 ViewController2 时设置此 closure 的值。
  3. 每当您 select 在 ViewController2tableView 中的一行时调用 closure 并在 closure 中传递 selected 值.
  4. 每当您从 closure 获得新值时更新 chosenQuestion,使用它又会使用 property observer.
  5. 更新 textField's

示例代码:

class ViewController1: UIViewController
{
    @IBOutlet weak var DiaryQuestionTextField: UITextField!

    var chosenQuestion = "" {
        didSet{
            //Textfield will be updated everytime a new value is set in chosenQuestion variable
            self.DiaryQuestionTextField.text = self.chosenQuestion
        }
    }

    @IBAction func showInspirationVC(_ sender: UIButton)
    {
        let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
        controller.handler = {[weak self](data) in
            self?.chosenQuestion = data
        }
        self.present(controller, animated: true, completion: nil)
    }
}

class ViewController2: UIViewController, UITableViewDelegate, UITableViewDataSource
{
    var handler: ((String)->())?
    var data = ["Question-1", "Question-2", "Question-3", "Question-4", "Question-5"]

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return self.data.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = self.data[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        self.dismiss(animated: true) {
            self.handler?(self.data[indexPath.row])
        }
    }
}

故事板:

首先尝试实现一个简单的用例。而且您不需要在这种方法中使用 segues,因为您是以编程方式呈现控制器的。

如有任何问题,请告诉我。

很简单,您只需要使用 viewDidLoad 中 UserDefaults 的值重新初始化 "chosenQuestion" 和 "chosenIdentifier" 就可以了。