Set condition on a segue function swift - 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
}
}

Related

Implementied a counter, but it's not updating

So I am trying to limit a booking form to a few slots only this is my code after they have booked and when they press a button it will decrease the availability by 1
class SuccessfulViewController: UIViewController {
var availability = 1
#IBAction func countBtn(_ sender: Any) {
availability -= 1
performSegue(withIdentifier: "backtoavailability", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let availabilityViewController = segue.destination as! AvailabilityViewController
availabilityViewController.countslots = String(availability)
}
}
and here's the other view controller code to display the availability left
class AvailabilityViewController: UIViewController {
#IBOutlet weak var availabilityLabel: UILabel!
var atfirst = "1"
var countslots = ""
#IBAction func trybookbtn(_ sender: Any) {
if availabilityLabel.text == "0" {
performSegue(withIdentifier: "full", sender: self)
}else {
performSegue(withIdentifier: "booking", sender: self)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
if countslots == ""{
availabilityLabel.text = atfirst
} else {
availabilityLabel.text = countslots
}
}
}
So now that the availability is 0, I will segue it to another view controller saying slots are full if the user tries to book and there is a home button as well. However, once I pressed the home button and checked the availability again, it is back to 1 and doesn't show 0 anymore. How can I let it stay at 0? Is it possible or do I have to implement a Firebase database?
I created the var at first as count slots would be empty b4 I booked a slot, is there a better way to do this?

Passing variable in swift with segue

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

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

Data from parse is not being passed through prepareForSegue

I want to get the objectId from parse and pass it through segue. But the objectId is passing over as an empty string:
class QueryViewController: UIViewController {
var objectIdFormParse = String()
#IBAction func makeQueryButtonTapped(_ sender: UIButton) {
makeSearchObject.saveInBackground { (success, error) in
if error == nil {
if let getObjectId = makeSearchObject.objectId {
self.objectIdFormParse = getObjectId
print("objectId in queryVC: \(self.objectIdForomParse)")
}
//Successfully saved
} else {
//Error, check error
}
}
performSegue(withIdentifier: resultsSegue, sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == resultsSegue
{
let destination = segue.destination as! ResultsViewController
destination.objectIdFromQueryVC = objectIdForomParse
}
}
}
The print statement prints the objectId correctly, but the segue passes empty.
You can pass the data through perform segue. just change perform segue line with following one:
performSegue(withIdentifier: resultsSegue, sender: objectIdForomParse)
And in your prepare for segue method add following lines:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == resultsSegue
{
let destination = segue.destination as! ResultsViewController
let objectIDParse = sender as! String
destination.objectIdFromQueryVC = objectIDParse
}
}
}
Perform segue when your error is nil since you are setting objectIdForomParse
only when your error is nil.
Update :
#IBAction func makeQueryButtonTapped(_ sender: UIButton) {
makeSearchObject.saveInBackground { (success, error) in
if error == nil {
if let getObjectId = makeSearchObject.objectId {
self.objectIdFormParse = getObjectId
print("objectId in queryVC: \(self.objectIdForomParse)")
performSegue(withIdentifier: resultsSegue, sender: self)
}
//Successfully saved
} else {
//Error, check error
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == resultsSegue
{
let destination = segue.destination as! ResultsViewController
destination.objectIdFromQueryVC = objectIdForomParse
}
}
}

Execute a function from other view controller

I have the following interfaces:
In the table view I set the new values for the user and I would like to call the function to update the data from the server when the button "Done" from the main view is pressed.
How I can do it?
I have tried:
#IBAction func doneTapped(_ sender: Any){
ProfileEditingTableViewController().updateData()
}
But all the text fields from the other view are null because it seems to be a new instance of ProfileEditingTableViewController.
updateData() can't be static.
class ProfileEditingViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func cancelButton(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func doneTapped(_ sender: Any) {
// Here I have to save the data from the other View
dismiss(animated: true, completion: nil)
}
}
class ProfileEditingTableViewController: UITableViewController {
func updateData() {
...
}
}
This line
ProfileEditingTableViewController().updateData()
is incorrect as it creates a new instance, you need to use delegate to access the presented ProfileEditingTableViewController
class ProfileEditingTableViewController: UITableViewController {
var profileInstance: ProfileEditingViewController!
}
When you present information from profile:
let info = //
info.delegate = self // here self is the profile instance
Then use:
profileInstance.updateData()
//
Edit: connect the segue source to the vc itself ( yellow circular icon ) , this inside ( ProfileEditingViewController)
self.performSegue(withIdentifier: "goToNext", sender: nil)
//
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "goToNext" {
let des = segue.destination as! ProfileEditingTableViewController
des.profileInstance = self
}
}