Save variables between View Controllers using a segue - ios

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

Related

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

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

Can not set the value in the label using delegate protocol

enter image description herei am making a program with delegate protocol in which we add value in text field in second controller and click save and this value is set to the label in the previous viewController
all the this are done but the value can not set to the label
Can someone please explain me what is triggering the messageData() method in the main ViewController?
import UIKit
protocol SenderViewControllerDelegate {
func messageData(data: String)
}
class NewViewController: UIViewController {
//MARK:- Properties
#IBOutlet weak var firstTextField: UITextField!
var delegate: SenderViewControllerDelegate?
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 SaveFirstValue(_ sender: Any) {
if delegate != nil{
if firstTextField.text != nil{
let data = firstTextField.text
delegate?.messageData(data: data!)
dismiss(animated: true, completion: nil)
}
}
}
}
import UIKit
class ViewController: UIViewController,SenderViewControllerDelegate {
//MARK:- Properties
#IBOutlet var firstLabel: 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.
}
//MARK:- Actions
func messageData(data: String) {
firstLabel.text = data
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let viewController : ViewController = segue.destination as! NewViewController
ViewController.delegate = self
}
}
}
Change this line
let viewController = segue.destination as! NewViewController
viewController.delegate = self
`ViewController.delegate = self` should be `viewController.delegate = self`
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let viewController : NewViewController = segue.destination as! NewViewController //destination is type NewViewController not ViewController
// ViewController.delegate = self //Wrong
viewController.delegate = self
}
}
You made mistake in the line ViewController.delegate = self it should be
viewController.delegate = self
means small "v" (object of ViewController)
UPDATED:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let objectOfVC = segue.destination as! NewViewController
objectOfVC.delegate = self
}
}
In ViewController Class set the delegate inside ViewDidLoad method like this:
newViewControllerObj. delegate = self
Without calling viewController Class, the delegate will not set So you have to call ViewController class inside NewViewController or other class which will call first like that:
let ViewControllerObj = ViewController()

Send a string from a viewController to another one

Please, before you mark this question as duplicate, I want to know why my code is failing, not to be send to another one that is working.
I am a newbie in swift and I would like to send a variable "um_words" (which is calculated when a button is clicked) from a viewController when the same button is clicked, save that variable in the secondViewController and show it in a textView. To do so I have tried with many modifications of this code, which is giving no errors in the console but not showing the value of the variable on the textView:
1st VC
import UIKit
import Foundation
class TransViewController: UIViewController {
#IBOutlet var trad_text: UITextView!
#IBOutlet var buttonTrad: UIButton!
#IBOutlet var labelsitoh: UILabel!
var num_words = 0
#IBAction func butCalc(_ sender: UIButton) {
let text = trad_text.text
num_words = (text?.components(separatedBy: " ").count)!-1
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var DestViewController : PaymentViewController = segue.destination as! PaymentViewController
DestViewController.num_words = String(num_words)
}
}
override func viewDidLoad() {
super.viewDidLoad()
trad_text!.layer.borderWidth = 1
trad_text!.layer.cornerRadius = 20
trad_text!.layer.borderColor = UIColor(red:0.22, green:0.26, blue:0.39, alpha:1.0).cgColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
2nd VC
import UIKit
import Foundation
class PaymentViewController: UIViewController {
#IBOutlet var labelImport: UITextView!
var num_words = String()
override func viewDidLoad() {
super.viewDidLoad()
labelImport.text = num_words
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I have ab hypothesis of why it is not working: the function "prepare" is not being called; it only goes to next VC when the button is clicked...
Thank you for your time.
The func prepare should be outside of the button action, it will be called when segue is triggered.
#IBAction func butCalc(_ sender: UIButton) {
let text = trad_text.text
num_words = (text?.components(separatedBy: " ").count)!-1
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var DestViewController : PaymentViewController = segue.destination as! PaymentViewController
DestViewController.num_words = String(num_words)
}
See:
IBAction func butCalc(_ sender: UIButton) {
let text = trad_text.text
num_words = (text?.components(separatedBy: " ").count)!-1
self.performSegue(withIdentifier: "yourSegueIdentifier", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "yourSegueIdentifier") {
var destViewController : PaymentViewController = segue.destination as! PaymentViewController
destViewController.num_words = String(num_words)
}
}
You have create a function in another function...
Please try this.
PS: I did not test this code

How can I run delegated method inside IBAction?

I have some methods in second view controller. I access them through delegate - inside func buttonSender. Main goal is to pass currentTitle of a button as an argument to a viewController.addNewMessage. What is the best way to do this?
ChatViewController:
protocol ReactToButtons {
func buttonSender(viewController: MyChatViewController)
}
class MyChatViewController: ChatViewController{
var delegate: ReactToButtons?
override func viewDidLoad() {
super.viewDidLoad()
delegate!.buttonSender(self)
}
}
ContainerViewController:
class ContainerViewController: UIViewController, ReactToButtons {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
viewController.addNewMessage(/*HERE GOES CURRENT TITLE*/)
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
}
I have change my answer to suit your code
class ContainerViewController: UIViewController, ReactToButtons {
var delegate: MyChatViewController!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
delegate = viewController
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
delegate!.addNewMessage(currentTitle)
}
}

Pass one variable from one viewcontroller to another viewcontroller

I new to swift language and know this question is duplicated.I`ve found several similar question and answer, but i could not able to figure out the problem.
I want to pass the value of detectionString variable to ResultViewController from ScanViewController.
ScanViewcontroller as below:
import UIkit
class ScanViewController: UIViewController {
var detectionString : String!
override func viewDidLoad() {
super.viewDidLoad()
detectionString = “SomeDetectedString”
}
override func prepareForSegue(segue: UIStoryboardSegue,sender: AnyObject!) {
if (segue.identifier == "MySegue") {
var svc = segue.destinationViewController as ResultViewController;
svc.detectedString = detectionString
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
The ResultViewController as below:
import UIkit
class ResultViewController: UIViewController {
var detectedString: String!
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor=UIColor.whiteColor()
println(detectedString)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
The println(detectedString) gives me no result. question is that how can get the variable from ScanViewController?
This may sound bizarre but there is nothing wrong with your code BUT it does not work as is. I used your code identically and it ignored the segue. Then I embedded ScanViewController in a navigation controller in the storyboard. I also put a call to self.performSegueWithIdentifier("MySegue", sender: self) in the ScanViewController viewDidLoad to initiate the segue. Then everything works like a charm. Your prepareForSegue is fine. Yuvrajsinh's suggestion is fine but not necessary (I tried it after changing DetailVC to ResultViewController). Without the navigation controller nothing works. segue.identifier is a string and it will work in a straight Swift string comparison.
Here is the code for ScanViewController:
import UIkit
class ScanViewController: UIViewController {
var detectionString : String!
override func viewDidLoad() {
super.viewDidLoad()
detectionString = "SomeDetectedString"
println(detectionString)
self.performSegueWithIdentifier("MySegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue,sender: AnyObject!) {
if (segue.identifier == "MySegue" || segue.identifier == "SegueFromButton") {
println("prepareForSegue")
var svc = segue.destinationViewController as ResultViewController;
svc.detectedString = detectionString
println("svc.detectedString: \(svc.detectedString)")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
and for ResultViewController:
import UIkit
class ResultViewController: UIViewController {
var detectedString: String!
override func viewDidLoad() {
println("Result Load View")
super.viewDidLoad()
self.view.backgroundColor=UIColor.whiteColor()
println("detectedString in Result: \(detectedString)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
your segue.identifier == "MySegue" is some how not comparing in the way it should.
replace your code with following function and you are done.
override func prepareForSegue(segue: UIStoryboardSegue,sender: AnyObject!) {
let segueName: String = segue.identifier!;
if (segueName == "MySegue") {
var svc = segue.destinationViewController as DetailVC;
svc.detectedString = detectionString
}
}
There are three options for you:
use prepareForSeguemethod to get the target ViewController and set up the property
set up delegate relationship between the two ViewControllers to communicate
set up Observer with NSNotificationCenter

Resources