Implementied a counter, but it's not updating - swift

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?

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

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

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

Swiching between 2 diferent NSViewControllers with data

I'm absolute newbie in Swift and OSX development, and I'm sorry if my question will be too noob. I want to understand principles of navigation between NSViewControllers.
I have my default ViewController, where are login and password fields and button to login. After click on button, returns token. And now I trying to change "view" to SecondViewController and save somewhere token, I will need it in future. How can I do it? and it possible to do this in function?:
#IBAction func loginButton(_ sender: Any) {
....
}
Thank you!
You need to use segues to perform this action.
First make the segues connections between the ViewControllers using to storyboard editor. After that you need to give the segues an identifier on the storyboard's attributes inspector. Then in your code you can call the new ViewController by the segue like the code below.
With this code you can pass the data using the button:
class ViewController: NSViewController {
var dataToPass: String = "DataToPass"
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func loginButton(_ sender: Any) {
performSegue(withIdentifier: NSStoryboardSegue.Identifier(rawValue: "segueIdentifier"), sender: self)
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier!.rawValue == "segueIdentifier" {
let destinationViewController = segue.destinationController as! ViewController2
destinationViewController.dataToReceive = dataToPass
}
}
}
class ViewController2: NSViewController {
var dataToReceive: String
override func viewDidLoad() {
super.viewDidLoad()
}
}
And with this code you will use the override viewWillAppear
class ViewController: NSViewController {
var dataToPass: String = "DataToPass"
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear() {
performSegue(withIdentifier: NSStoryboardSegue.Identifier(rawValue: "segueIdentifier"), sender: self)
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier!.rawValue == "segueIdentifier" {
let destinationViewController = segue.destinationController as! ViewController2
destinationViewController.dataToReceive = dataToPass
}
}
}
class ViewController2: NSViewController {
var dataToReceive: String
override func viewDidLoad() {
super.viewDidLoad()
}
}
In both cases you need to assure the data you want to pass to the other view controller is not null.

How to send multiple variables in one single sender?

I'm trying to send multiple variables in one single sender to show it in the Viewcontroller that it's connected to a segue named menuENG. I have five buttons and each button should send different information because is a dictionary and each button is a word. But I want to do this thru one sender. I tried the following code to make it but it is not working.
p.s.: I tried making an array but Xcode goes crazy.
#IBAction func abstractionENG(sender:UIButton) {
return perfomanceWithIdentifier("menuENG",sender:nil)
}
I think you can send the dictionary and there is something wrong with this line return perfomanceWithIdentifier("menuENG",sender:nil)
Anyway you can seperatly identify which button is clicked by tag and create dictionary on base of clicked button now you can send the complete dictionary to the sender.
#IBAction func abstractionENG(sender:UIButton) {
var dictSendData:[String:Any] = [:]
if sender == btn1
{
dictSendData.updateValue("abc", forKey: "key1")
dictSendData.updateValue("pqr", forKey: "key2")
}
else if sender == btn2
{
dictSendData.updateValue("xyz", forKey: "key1")
dictSendData.updateValue("123", forKey: "key2")
}
else
{
dictSendData.updateValue("123", forKey: "key1")
dictSendData.updateValue("abc", forKey: "key2")
}
self.performSegue(withIdentifier:"menuENG", sender: dictSendData)
}
1- assign segue action to IBAction function - assign tag id to ever button
you have already implemented it .
2- your IBAction function should run another function to run performSegue function
example :
self.performSegue(withIdentifier: "openAnotherViewController",sender: sender)
3- go to destination view Controller and create reciver variables "Maybe you can use optionals " .
var receiverInt :Int = 0
var receiverInt2 :Int = 0
3- go to the source view Controller and pass variables
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected variable/object to the new view controller .
if segue.identifier == "openAnotherViewController" {
let destinationController = segue.destination as! OtherViewControllerClass Name
// identify button by tag number
if (sender as! UIButton).tag == 200 {
destinationController.receiverInt = self.sourceInt
}else{
destinationController.receiverInt2 = self.sourceInt2}
}
}
Thank you everyone for the help fixed the issue by this way >
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
/* The following functions containts a group of conditionals which will change the scene depending of the IBAction selected */
#IBAction func abstractionENG(sender: UIButton) {
let data = [DiccioModel.abstraction().nameEng,DiccioModel.abstraction().descriptionEng,DiccioModel.abstraction().linkEng]
performSegueWithIdentifier("menuENG", sender: data)
}
#IBAction func webBrowserENG(sender: UIButton) {
let data = [DiccioModel.webBrowser().nameEng,DiccioModel.webBrowser().descriptionEng,DiccioModel.webBrowser().linkEng]
performSegueWithIdentifier("menuENG", sender: data)
}
#IBAction func latencyENG(sender: UIButton) {
let data = [DiccioModel.latency().nameEng,DiccioModel.latency().descriptionEng,DiccioModel.latency().linkEng]
performSegueWithIdentifier("menuENG", sender: data)
}
#IBAction func conditionalENG(sender: UIButton) {
let data = [DiccioModel.conditional().nameEng,DiccioModel.conditional().descriptionEng,DiccioModel.conditional().linkEng]
performSegueWithIdentifier("menuENG", sender: data)
}
#IBAction func operatingSystemENG(sender: UIButton) {
let data = [DiccioModel.os().nameEng,DiccioModel.os().descriptionEng,DiccioModel.os().linkEng]
performSegueWithIdentifier("menuENG", sender: data)
}
#IBAction func abstractionESP(sender: UIButton) {
let data = [DiccioModel.abstraction().nameEsp,DiccioModel.abstraction().descriptionEsp,DiccioModel.abstraction().linkEsp]
performSegueWithIdentifier("menuESP", sender: data)
}
#IBAction func webBrowserESP(sender: UIButton) {
let data = [DiccioModel.webBrowser().nameEsp,DiccioModel.webBrowser().descriptionEsp,DiccioModel.webBrowser().linkEsp]
performSegueWithIdentifier("menuESP", sender: data)
}
#IBAction func latencyESP(sender: UIButton) {
let data = [DiccioModel.latency().nameEsp,DiccioModel.latency().descriptionEsp,DiccioModel.latency().linkEsp]
performSegueWithIdentifier("menuESP", sender: data)
}
#IBAction func conditionalESP(sender: UIButton) {
let data = [DiccioModel.conditional().nameEsp,DiccioModel.conditional().descriptionEsp,DiccioModel.conditional().linkEsp]
performSegueWithIdentifier("menuESP", sender: data)
}
#IBAction func operatingSystemESP(sender: UIButton) {
let data = [DiccioModel.os().nameEsp,DiccioModel.os().descriptionEsp,DiccioModel.os().linkEsp]
performSegueWithIdentifier("menuESP", sender: data)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "menuENG") || (segue.identifier == "menuESP"){
if let destinationViewController = segue.destinationViewController as? DefinitionViewController{
if let data = sender as? Array<String>{
destinationViewController.tittle = data[0]
destinationViewController.def = data[1]
destinationViewController.link = data[2]
}
}
}
}
PS: note this code is connected to the DefinitionViewController ( Controller of the view) and to a model. ( project was made by M.V.C way).
Again Thx everyone for your help. hope the code help other people in the future.