viewDidLoad() load twice when passing data with Navigation Controller - SWIFT - ios

I'm new to swift development. I'm trying to pass data from one UiViewController to Another UIViewController with NavigationController. I was able to pass the data, but for some reason, it loads the viewDidLoad() twice on the second UIViewController. Below is my code.
ViewController
class ViewController: UIViewController {
var option = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// Dine In Btn
#IBAction func dineinBtn(_ sender: Any) {
self.option = "Dine In"
performSegue(withIdentifier: "dinein", sender: self)
}
// Take Out Btn
#IBAction func takeoutBtn(_ sender: Any) {
self.option = "Take Out"
performSegue(withIdentifier: "takeout", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! QualityViewController
vc.option = self.option
}
#IBAction func unwindToVC1(segue:UIStoryboardSegue) { }
}
QualityViewController
class QualityViewController: UIViewController {
var option = ""
override func viewDidLoad() {
super.viewDidLoad()
option += option
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

The reason may be that you hook buttons dineinBtn and takeoutBtn as the segue source , so the IB segue is triggered plus this
performSegue(withIdentifier: "takeout", sender: self)
Another reason may be that you copied the buttons in IB so each one is hooked to 2 IBActions in code

Related

iOS swift prepareForSegue cannot pass data between two viewcontroller

This is my code of two viewcontroller, need pass "numberToDisplay" from class bookTwo to class bookThree, but it not work, always show 0 in bookThree.
I am using swift3 on ios 10, xocod 8.
bookTwo:
import UIKit
import Foundation
class bookTwo: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ms1"{
let destinationVC = segue.destination as? bookThree;
destinationVC?.numberToDisplay = 7
}
}
}
bookThree
import UIKit
class bookThree: UIViewController {
var numberToDisplay = 0
#IBOutlet weak var showType: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
showType.text = "Tapped \(numberToDisplay) times."
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In Swift 3, the signature for method "prepareForSegue" has changed. So replace the code for "prepareForSegue" with this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ms1"{
let destinationVC = segue.destination as? bookThree
destinationVC?.numberToDisplay = 7
}
}

#IBAction to performSegue

I have the following:
class Settings: UIViewController {
#IBAction func CitySend(sender: AnyObject) {
self.performSegue(withIdentifier: "senddata", sender: self)
}
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "senddata" {
let Mainview = segue.destination as! ViewController
Mainview.label = textField.text!
}
}
}
My mainview looks like this:
class ViewController: UIViewController {
#IBOutlet var city: UILabel!
var label: String = ""
override func viewDidLoad() {
super.viewDidLoad()
city.text = label
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
im not sure, if this is how i should even do this, but to me the logic is that i only want to allow this segue to pass a string to my label in my mainview if the button is pressed (Like a save button)
However as to what i have made now, nothing happens, and it gives me the 1: signal SIGABRT error, whenever i press the button.
Use the following code:
ViewController.swift
import UIKit
class ViewController: UIViewController, SecondViewControllerProtocol{
#IBOutlet weak var dataLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func navigateToSecondViewControllerOnButtonClick(_ sender: AnyObject) {
let secondVC: ViewController2 = storyboard?.instantiateViewController(withIdentifier: "viewcont2") as! ViewController2
secondVC.delegate = self
self.navigationController?.pushViewController(secondVC, animated: true)
}
func saveData(data: String){
dataLabel.text = data
}
}
ViewController2.swift
import UIKit
protocol SecondViewControllerProtocol {
func saveData(data: String) // this function the first controllers
}
class ViewController2: UIViewController {
var delegate: SecondViewControllerProtocol?
#IBOutlet weak var dataTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func saveButtonClicked(_ sender: AnyObject) {
delegate?.saveData(data: dataTextField.text!)
}
}
Storyboard screenshot:
Please check my GitHub link below to test sample:
https://github.com/k-sathireddy/PassingDataThroughSegue
#IBAction func CitySend(sender: AnyObject) {
self.performSegue(withIdentifier: "senddata", sender: textField.text)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch (segue.identifier, segue.destination, sender) {
case (.Some("senddata"), let controller as ViewController, let text as String):
controller.label = text
default:
break
}
}

prepareForSegue is not called after performSegueWithIdentifier

I'm new to iOS development. There are many duplicated questions (Sorry). But I could not solve this problem.
prepareForSegue is not called after calling performSegueWithIdentifier.
The show segue identifier is named as 'segue1'.
Ctrl-Dragged from ViewController to DetailViewController.
Am I missing something?
ViewController.swift:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func buttonTapped(sender: AnyObject) {
print("ViewController - buttonTapped()")
performSegueWithIdentifier("segue1", sender: self)
}
override func performSegueWithIdentifier(identifier: String, sender: AnyObject?) {
print("ViewController - performSegueWithIdentifier(): \(identifier)")
}
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
print("ViewController - shouldPerformSegueWithIdentifier()")
return true
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
print("ViewController - prepareForSegue(): \(segue.identifier!)")
}
}
DetailViewController.swift:
class DetailViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("DetailViewController - viewDidLoad()")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Here is a screenshot of storyboard.
Output (after the button is tapped)
ViewController - buttonTapped()
ViewController - performSegueWithIdentifier(): segue1
You're not calling super - add the following to send the message to the parent class (which will in turn fire off the segue)
super.performSegueWithIdentifier(identifier, sender: sender)

Save variables between View Controllers using a segue

I use Swift and Xcode 6.4 and I would like to pass a variable from one View Controller to another using a Segue.
When you press the button, the variable duration should give the value to the ViewController2. In the ViewController2 I want to use this variable again.
Main.storyboard button identifier called Test1
How can I do that? Can you help me with my code? Whats wrong?
Thanks
Code ViewController1:
import UIKit
class ViewController1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func ButtonTapped(sender: AnyObject) {
var duration = 1.0
self.performSegueWithIdentifier("Test1", sender: duration)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier = "Test1") {
let secondViewController = segue.destinationViewController as ViewController2
let duration = sender as Double
secondViewController.duration = duration
}
}
}
Code ViewController2:
import UIKit
class ViewController2: UIViewController {
var duration:Double?
var result = duration + 2.0
println(\(result))
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
var duration = Double() // now "duration" is global
#IBAction func ButtonTapped(sender: AnyObject) {
duration = 1.0
self.performSegueWithIdentifier("Test1", sender: duration)
// VVV Any new variable created in this scope will be deallocated
} // HERE
//Then this scope starts...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "Test1") {
let secondViewController = segue.destinationViewController as ViewController2
// delete this... duration = sender as Double
secondViewController.duration = duration
}
}

Receiver has no segue with identifier 'contact_segue'

I have a problem that the self.performSegueWithIdentifier("contact_segue", sender: self) do not work and complain that Receiver has no segue with identifier 'contact_segue' even i have the identifier. I have used the SWReveal framework to build the left-side sliding menu which is work with table view(class: slidingMenuController). After I clicked the cell to call function changeView of MainNavigationController to do changing views.
import UIKit
class MainNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool){
super.viewDidAppear(false)
self.performSegueWithIdentifier("Home", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "Contact_se" {
}
}
func changeView(){
self.performSegueWithIdentifier("contact_segue", sender: self)
}
}
The changeView which is called by an a left-side sliding menu (class: slidingMenuController) in a tablecell:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItemMenu = arrayOfSlider[indexPath.row]
let mainNav = MainNavigationController()
mainNav.changeView()
}
Just add this code self.performSegueWithIdentifier("contact_segue", sender: self) on your didSelectRowAtIndexPath? I believe there's no need for the MainNavigationController here.

Resources