Swift 3 - 将数据从一个视图传递到另一个视图

Swift 3 - Passing Data from one view to another

我将以我严格来说是一名涉足 xcode 的设计师这一事实作为这个问题的开头。我正在尝试构建一个 'dumb' 原型。

我正在尝试设置 2 个 VC。第一个 VC 有一个文本字段,允许用户输入搜索参数,在点击 "Return" 后,它应该将该参数传递给下一个 VC。同样在这个特定的 VC 上,我在导航栏中设置了一个 'back' 按钮。

我遇到的问题是我无法获得第一个 VC 的后退按钮的代码来使用传递变量的代码。每当我点击第一个视图控制器上的后退按钮时,它都会导致应用程序崩溃。 Xcode 指出问题出在传递变量的代码中。这是 VC 的代码。

import UIKit

class SearchViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var searchText: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
    searchText.delegate = self
    searchText.becomeFirstResponder()
    // Do any additional setup after loading the view.
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    var destinationController = segue.destination as! ResultsViewController
    destinationController.searchItem = searchText.text!
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if searchText.text != "" {
        performSegue(withIdentifier: "resultsSegue", sender: self)
        textField.resignFirstResponder()
        return false
    }

   // self.view.endEditing(true)

    return true
}



override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)
    self.navigationItem.hidesBackButton = true
}



}

结果视图控制器的代码是

import UIKit

class ResultsViewController: UIViewController {

@IBOutlet weak var userSearchInputLabel: UILabel!
@IBAction func btnReturnToSearch(_ sender: Any) {
    performSegue(withIdentifier: "segueBackToSearch", sender: self)
}


var searchItem = String()



override func viewDidLoad() {

    super.viewDidLoad()
    userSearchInputLabel.text = searchItem
     self.extendedLayoutIncludesOpaqueBars=true;
    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)
    self.navigationItem.hidesBackButton = true
}

@IBAction func unwindToResults(segue:UIStoryboardSegue) { }

}

如果你的 SearchViewControllerinitial VC 那你为什么要放一个 back 按钮呢?你想让它去哪里Go Back to?我认为它不应该在那里。
此外,除非您真的需要在 Xcode 中以编程方式执行操作,否则您应该只使用 StoryboardSearchViewController 嵌入 NavigationController(select Controller 然后从菜单:Editor-> Embed in -> Navigation Controller).

然后从 SearchViewControllercontroller icon on the topResultViewController 创建 segue 并且您可以像您已经知道的那样为 segue 设置标识符(因为您在代码)。
在你的 ResultViewController 中,如果你已经完成了我上面提到的步骤,那么你不需要 button 代替 returnToSearch,你可以删除 @IBAction for btnReturnToSearch(_ sender: Any)。因为您将免费获得 <Back 按钮作为 ResultViewController 到 return 到 SearchVeiwController 顶部的 Navigation Item

*** 根据最后一条评论更新 ****
好的。我终于明白你的问题了。在你的 prepare(for:sender) 中。你需要 。检查 Segue 标识符:

if  segue.identifier  == "CHANGE_ME_WITH_YOUR_SEGUE_FOR_RESULT_IDENTIFIER"  {
 ...
}

在您将搜索结果传递给 .结果视图控制器。当你继续往回走时,你不会去 ResultViewController,而是去 MainViewController

其实我知道我做错了什么。由于我的搜索视图控制器中有多个转场,我需要 运行 在执行将数据传递到结果视图控制器的转场之前检查转场标识符名称。因为我没有那张支票,所以它导致了应用程序崩溃。现在我只需要弄清楚如何阻止我的标签栏导航消失...

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "resultsSegue" {
    let destVC = segue.destination as! UINavigationController
    let destinationController = destVC.topViewController as! ResultsViewController
    destinationController.searchItem = searchText.text!
    }
}