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

Posted

技术标签:

【中文标题】Swift 3 - 将数据从一个视图传递到另一个视图【英文标题】:Swift 3 - Passing Data from one view to another 【发布时间】:2017-06-18 12:18:08 【问题描述】:

我将用我严格来说是一名涉足 xcode 的设计师来作为这个问题的开头。我正在尝试构建一个“愚蠢”的原型。

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

我遇到的问题是我无法让第一个 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)  


【问题讨论】:

【参考方案1】:

如果您的SearchViewControllerinitial VC,那么您为什么要在其中放置back 按钮?你想在哪里Go Back to?我认为它不应该在那里。 此外,除非您真的需要在 Xcode 中以编程方式执行操作,否则您应该使用 StoryboardSearchViewController 嵌入到 NavigationController 中(然后从菜单中选择 ControllerEditor-> Embed in -> Navigation Controller)。 然后从SearchViewControllercontroller icon on the topResultViewController 创建segue,您可以为segue 设置标识符,就像您已经知道的那样(在您的代码中使用它)。 在你的ResultViewController 中,如果你已经完成了我上面提到的步骤,那么你不需要button 来代替returnToSearch,你可以删除@IBAction for btnReturnToSearch(_ sender: Any)。因为您将在ResultViewController 顶部获得<Back 按钮Navigation Item 以免费返回SearchVeiwController

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

if  segue.identifier  == "CHANGE_ME_WITH_YOUR_SEGUE_FOR_RESULT_IDENTIFIER"  
 ...

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

【讨论】:

SearchViewController 不是初始视图。在它之前有一个主 VC,Search VC 将链接回它。我刚刚尝试将导航控制器嵌入到结果视图控制器中。所以现在搜索和结果 VC 都有导航控制器。但是,当我尝试将在 Search VC 中输入的值传递给 Results VC 时,应用程序仍然崩溃。当我注释掉这些代码行时,它可以正常工作(尽管没有传递任何信息) 控制台将这些信息返回给我“无法将 'UINavigationController' (0x1066124e8) 类型的值转换为 'Application11.ResultsViewController” 请提供您的项目仍然会崩溃的最少内容。否则很难帮你调试问题。 我有一个嵌入了选项卡和导航控制器的主视图控制器。从该视图中,它转到搜索视图控制器。它有一个文本字段,用户可以在其中键入搜索参数,然后将其传递给结果视图控制器。在搜索视图控制器中,我有一个左侧导航栏项目,我试图将其链接回主视图控制器。该应用程序在尝试返回主视图控制器时崩溃。调试器似乎指向我用来将搜索变量传递给结果 VC 的代码。 override func prepare(for segue: UIStoryboardSegue, sender: Any?) let destVC = segue.destination as! UINavigationController 让destinationController = destVC.topViewController 一样! ResultsViewController 目的地控制器.searchItem = searchText.text! 【参考方案2】:

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

 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!
    

【讨论】:

以上是关于Swift 3 - 将数据从一个视图传递到另一个视图的主要内容,如果未能解决你的问题,请参考以下文章

在swift 3中将json id从一个表视图控制器传递到另一个表视图控制器

使用 Segue 在 Swift 中将带有数据的对象从一个视图传递到另一个视图

Swift 4:将数据从集合视图单元传递到另一个没有故事板的视图控制器

如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?

如何将数据从表视图传递到另一个视图控制器

如何将触摸事件从一个视图传递到另一个视图