Passing variable in swift with segue - swift

I'm using segue to open a new window in a xcode app.
The segue is correct, when I tap on the button the new window is shown.
I want to pass a string variable from FirstViewController to DetailViewController but I can't set the variable in the DetailViewController.
This is the code in FirstViewController:
if control == view.rightCalloutAccessoryView {
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let controller = segue.destination as! DetailViewController
controller.Name = "test"
}
performSegue(withIdentifier: "showdetail", sender: self)
}
And this the DetailViewController code
class DetailViewController: UIViewController, WKNavigationDelegate {
var Name: String = ""
override func viewDidLoad() {
super.viewDidLoad()
print(Name)
}
}
Where am I doing wrong?

The method prepare(for must be on the top level of the class.
And please name variables according to the guidelines with starting lowercase letter
func someMethod()
{
if control == view.rightCalloutAccessoryView {
performSegue(withIdentifier: "showdetail", sender: self)
}
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let controller = segue.destination as! DetailViewController
controller.name = "test"
}
}

Related

Set condition on a segue function swift

In a single button, i put both alart system and a pop up view. If the text fields are blank then it will send an alart. If everything is okay then it will show popup view. Alart system and pop up is conflicting. How do I set conditon to segue function when to perform or not?
The function is not written proper. I can understand. But I am confused writing it. How do i call the overrride func?
func stateCondition(state: Bool) {
if state {
print("Entered into the state") //entering into the func
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "info"{
_ = segue.destination as! InfoViewController
}
if segue.identifier == "popUp" {
let vc = segue.destination as! PopUpViewController
vc.age = Double(ageTextField.text!)!
vc.gender = genderTextField.text!
vc.bmi = Double(bmiLabel.text!)!
print("Entered into the segue") //is not entering into this func
}
}
}
}
Try to read the code and comments.
First of all, the method func prepare(for segue: UIStoryboardSegue, sender: Any?) must not be in another method. Somehow you managed to squeeze it in func stateCondition(state: Bool) . Second you are not calling performSegue(withIdentifier: identifier, sender: self) anywhere. You probably should :) Check out the code, hope it helps. I remember my first segue, it took me some time to understand what is going on.
class ViewController: UIViewController {
#IBOutlet private var ageTextField: UITextField!
#IBOutlet private var genderTextField: UITextField!
#IBOutlet private var bmiLabel: UILabel!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 3
// This method gets called and there you do your stuff with respective VCs
if segue.identifier == "info", let infoViewController = segue.destination as? InfoViewController {
// 3.1
// If the identifer is set to INFO then you go to the InfoViewController and assigne message
infoViewController.message = "Some fields are empty"
} else if segue.identifier == "popUp", let popUpViewController = segue.destination as? PopUpViewController {
// 3.2
// If the identifer is set to POPUP then you go to PopUpViewController and assign age, gender and bmi
popUpViewController.age = "33"
popUpViewController.gender = "male"
popUpViewController.bmi = "20"
} else {
print("Identifer is none of the above")
}
}
#IBAction private func buttonTapped(_ sender: Any) {
// 1.
// First you need to figure out where you want to take the user
// You do that in the method getSegueIdentifier() where you get the identifier
let identifier = getSegueIdentifier()
// 2.
// Then you performSegue with that identifer
performSegue(withIdentifier: identifier, sender: self)
}
private func getSegueIdentifier() -> String {
if ageTextField.text?.isEmpty == true && genderTextField.text?.isEmpty == true && bmiLabel.text?.isEmpty == true {
return "info"
} else {
return "popUp"
}
}
}
class InfoViewController: UIViewController {
var message = ""
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showAlert()
}
func showAlert() {
// show alert with message
print(message)
}
}
class PopUpViewController: UIViewController {
var age = ""
var gender = ""
var bmi = ""
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
showPopUp()
}
func showPopUp() {
// show popUp with age gender and bmi
print(age, gender, bmi)
}
}
There is general misunderstanding: You must not call prepare(for segue – besides the syntax is wrong anyway – the function is called by the framework just before the segue is performed.
You probably mean something like
func stateCondition(state: Bool) {
if state {
print("Entered into the state") //entering into the func
performSegue(withIdentifier: "info", sender: nil)
} else {
performSegue(withIdentifier: "popUp", sender: nil)
}
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "popUp" {
let vc = segue.destination as! PopUpViewController
vc.age = Double(ageTextField.text!)!
vc.gender = genderTextField.text!
vc.bmi = Double(bmiLabel.text!)!
print("Entered into the segue") //is not entering into this func
}
}

How to perform prepareForSegueFunction on ViewController load?

I am trying to perform a segue when the ViewController loads so it can trigger the prepareForSegue function.
I have tried using performselector but it does not work. Any suggestions?
func doSegue() {
performSegue(withIdentifier: "doSegue", sender: nil)
}
perform(Selector(("doSegue")), with: nil, afterDelay: 1)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let guest = segue.destination as! WarningTableViewController
//code
}
It says it cannot find a selector named doSegue.
The code you posted is confusing.
Why there's a perform(Selector... there?
Here's a working example:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
performSegue(withIdentifier: "doSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "doSegue" {
print("It works")
// Or call another function, e.g. "doSomethingElse()"
}
}
}
Also double-check the segue declaration in Interface Builder:

Attempting to pass data from one viewcontroller to another using segues

I have two viewcontrollers setup and set the segue connections as well. I'm attempting to pass data from one of the VC's to the other. Using the below code and using the func override works. What i want to do is only have the override func prepare fire off when a button is pressed and when i paste the override func code into a button action, it doesnt work - the label on the first VC doesnt update - it stays to the default value i set.
First ViewController code:
var testLabel1:String = "default"
#IBOutlet weak var testLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
testLabel?.text = testLabel1
// Do any additional setup after loading the view.
}
Second ViewController code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.destination is ViewController
{
let vc = segue.destination as? ViewController
vc?.testLabel1 = "Success"
}
}
Button action that ive tried
#IBAction func actionBtn(_ sender: Any) {
func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.destination is ViewController
{
let vc = segue.destination as? ViewController
vc?.testLabel1 = "Success"
}
}
}
You need to trigger it with performSegue
class FirstVc:UIViewController {
#IBOutlet weak var lbl:UILabel!
#IBAction func goToSecond(_ sender: Any) {
self.performSegue(withIdentifier:"YourSegueName",sender:nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "YourSegueName" {
let vc = segue.destination as! SecondVC
vc.testLabel1 = "Success"
}
}
func setData(_ str:String){
self.lbl.text = str
}
}
class SecondVC:UIViewController {
var testLabel1 = ""
weak var delegate:FirstVc?
func goBack() {
self.delegate?.setData("FromSecond")
self.dismiss(animated: true, completion: nil)
}
}

Two "performSegue" in same class to different Viewcontrollers

I am trying to go to two different VC with two different buttons. With the 'newGeneratedListBtn i only want to go to vc1. With the 'newEmptyList' button i want to go to vc3 with a bool value which works. But when i click first button 'newGeneratedListBtn' to go to vc1 I get error: "Could not cast value of type 'AppName.vc1' to 'AppName.vc3'.
Seems like when i click button to vc1 it tries to send the same values as i want to send to vc3. How can i solve this?
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.
}
let value = true
//Button to VC1
#IBAction func newGeneratedListBtn(_ sender: UIButton) {
performSegue(withIdentifier: "unwindSegueToVC1", sender: self)
}
//Value to send to VC2
override func prepare (for segue: UIStoryboardSegue, sender: Any!) {
let vc = segue.destination as! ListView
vc.newEmptyListValue = value
}
//Button to VC2
#IBAction func newEmptyList(_ sender: UIButton) {
performSegue(withIdentifier: "valueSender2", sender: self)
}
}
You need to cast for a specific identifier
override func prepare (for segue: UIStoryboardSegue, sender: Any!) {
super.prepare(for:segue,sender:sender)
if segue.identifier == "valueSender2" {
let vc = segue.destination as! ListView
vc.newEmptyListValue = value
}
else {
// it's unwindSegueToVC1
}
}
as both
performSegue(withIdentifier: "unwindSegueToVC1", sender: self)
performSegue(withIdentifier: "valueSender2", sender: self)
with call prepare
The problem is there is only one implementation of prepare(for:sender:), like this:
override func prepare (for segue: UIStoryboardSegue, sender: Any!) {
let vc = segue.destination as! ListView
vc.newEmptyListValue = value
}
Both of your segues pass through that one method. You must use a switch or other condition to figure out which segue this is, and send the info appropriate to that segue.

Could not cast value of type 'Work.Login' (0x10c5edd20) to 'Work.DataBaseConn'

I have a problem with my second viewController when trying to send data with segue. The code of Login is:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let secondView = segue.destination as! DataBaseConn
secondView.user=TextUsername.text!
secondView.pass=Pass.text!
}
override func viewDidLoad() {
super.viewDidLoad()
self.performSegue(withIdentifier: "sendData", sender: self)
}
I get the error at this line:
let secondView = segue.destination as! DataBaseConn
Both views have the custom class set.