简体   繁体   中英

Swift 3 - Passing Data from one view to another

I'll preface this question with the fact that I'm strictly a designer dabbling in xcode. I'm trying to build a 'dumb' prototype.

I am trying to set up 2 VC's. The first VC has a text field that allows a user to type in a search param and upon hitting "Return" it should pass that param to the next VC. Also on this particular VC I have a 'back' button setup in the navigation bar.

The problem I'm having is that I can't get the code for the 1st VC's back button to work with the code for passing the variable. It causes the application to crash anytime I hit the back button on the first view controller. Xcode notes that the problem is somewhere in the code for passing the variable. Here's the code for both VC's.

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
}



}

The Results View Controller's code is

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) { }

}

If your SearchViewController is the initial VC then why would you put a back button there? Where you want it to Go Back to ? I think it should not be there.
Also unless you really need to do things programmatically in Xcode, you should just use Storyboard do embed the SearchViewController inside NavigationController (select the Controller then from menu: Editor-> Embed in -> Navigation Controller ).

Then create segue from controller icon on the top of the SearchViewController to the ResultViewController and you could set identifier for the segue like you already knew (as you use it in your code).
In your ResultViewController , if you have did the steps I mentioned above, then you don't need button for returnToSearch and you could delete the @IBAction for btnReturnToSearch(_ sender: Any) . As you will get the <Back button as Navigation Item on the top of ResultViewController to return to SearchVeiwController for free.

*** Update based on the last comment ****
Okay. I finally understood your issue. In your prepare(for:sender) . you need to . check the Segue Identifier:

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

before you pass down the search result to the . ResultViewController. As when you segue back, you are not going to the ResultViewController but the MainViewController .

Actually I see what I was doing wrong. Since there were multiple segues in my Search View Controller, I needed to run a check on the segue identifier name before performing the segue that was passing data to the Results View Controller. Because I didn't have that check, it was causing the app to crash. Now I just have to figure out how to stop my tab bar navigation from disappearing...

 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!
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM