Do some code before segue? - swift

I wanted to make a converter,
This is how it works:
On the initial screen, it asks from which unit you wanna convert,
then when the user clicks on the button it sends the title of the button as string to the next view controller,
then using the if statement and checking the the title string to the all units like inch, meter, yard, etc it identifies from which unit we are converting from,
then on 'Editing did change' function in the text field it converts and gives the answer
I have a problem when it recognises and sends the button title to the next view, what is happening is it is not carrying out the touch up inside function and directly sending the from string which doesn't carry the button title,
Here is the code
class lengthconversions: UIViewController {
var from = "From"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "answer" {
if let destinationVC = segue.destinationViewController as? lengthconversionsanswer{
destinationVC.from = from
}
}
}
#IBAction func fromunit(sender: AnyObject) {
let buttonTitle = (sender as? UIButton)?.titleLabel?.text
from = buttonTitle!
print(from)
}}
How can I do that the touch up inside function happens and then the
data transfer through the segue.
p.s - The button to which the segue is hooked is the same to which the
Touch up inside function is used

The prepareForSegue function has an argument of sender. If you are performing the segue because of a button click, then the sender will be the button.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "answer" {
if let destinationVC = segue.destinationViewController as? lengthconversionsanswer,
let button = sender as? UIButton {
destinationVC.from = button.titleLabel?.text!
}
}
}

Related

Problem with cast on the function prepareForSegue

I have an error with my segue. When I click on the information button the application crashes. In the title View I have multiple segues. The first one is for send array to the register view and the others is for opening my information Pop Up.
The message error is:
And this is the main StoryBoard:
How do I fix this?
If you have 2 segues then you need to differentiate them with the identifier
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifer == "toPopUp" {
if let yourVC = segue.destination as? YourPopController {
// set data
}
}
else {
if let yourVC = segue.destination as? RegisterViewController {
// set data
}
}
}

Swift Send data from Popup to Another View

I'm trying to send data from popup view to DataView.
it actually works ! .However, when I go back to popup view to edit the text it doesn't show the text that was entered and sent to DataView.
I'm sending the data through protocol.
PopupView
protocol DataEnteredDelegate: class {
func userDidEnterInformation(data: String)}
#IBAction func DoneButton(_ sender: Any) {
if let data = openTextView.text {
delegate?.userDidEnterInformation(data: data)
self.dismiss(animated: true, completion: nil)
}
}
DataView
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "openSummary" {
let sendingVC: popupViewController = segue.destination as! popupViewController
sendingVC.delegate = self
}
}
// Protocol receving data from popup
func userDidEnterInformation(data: String) {
addJobSum.text = data
}
After the PopupViewController gets dismissed, it gets destroyed and no new instances are able to know what an old instance had as a text value for the Text View.
To fix it - create a string property inside PopupViewController and initialize the Text View's text property with its value inside some method, such as viewDidLoad():
class PopupViewController: UIViewController {
var textData: String?
/* more code */
func viewDidLoad() {
/* more code */
if let data = textData {
openTextView.text = data
}
}
}
Then, you'll have to inject the proper / needed text for textData inside prepare(for:) method (right before it's presented):
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "openSummary" {
let sendingVC = segue.destination as! PopupViewController
sendingVC.delegate = self
// This is the new line to be added:
sendingVC.textData = addJobSum.text
}
}

how to pass data to multiple viewcontrollers from the same button

Here's another version of one of the most popular questions on stackoverflow. Sorry. Thank you.
I have a viewcontroller that has 30 buttons. Each of these buttons can segue to one of 20 viewcontrollers based on a variable that is sent from a previous viewcontroller.
I know how to send data from one viewcontroller to another, and I know how to have a button connect to multiple viewcontrollers dependent on a passed variable, but I don't know how to pass a variable from a button to whatever viewcontroller is specified from the variable...
My viewcontroller looks like this:
#IBAction func didTapButton(_ sender: UIButton) {
if passedvariable == "A" {
performSegue(withIdentifier: "ToA", sender: self)
if passedvariable == "B" {
performSegue(withIdentifier: "ToB", sender: self)
}
I tried adding something like this...
#IBAction func didTapButton(_ sender: UIButton) {
if passedvariable == "A" {
performSegue(withIdentifier: "ToA", sender: self)
let send = segue.destination as! AViewController
send.NewVariableToSend = (sender as! UIButton).title(for: .normal)!}
}
But that's not working... I feel like I'm close but can't connect the dots yet. Any help is greatly appreciated, thanks!
How are you accessing the actual segue from the IBAction method of your UIButton?
This approach is wrong. Use PrepareForSegue method to pass your data to next ViewController. Its a predefined method so all you need is to override this method in your ViewController class.
Try this..
Note:
guard let is used to get rid of crash if you tried to pass any nil value to your next ViewController.
#IBAction func didTapButton (_ sender: Any) {
//First get the clickedButton Object if you do not have IBOutlet of that button
guard let clickedButton = sender as? UIButton else {return}
//Pass the clicked button to Segue perform as a sender
self.performSegue(withIdentifier: "yourSegueIdentifier", sender: clickedButton)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourSegueIdentifier" {
//Now get you destination viewcontroller and type cast it into your desired ViewController class
guard let nextVC = segue.destination as? YourViewController else {return}
//Now convert the sender into your clicked button because you have previously set the clickedButton as sender when you try to perform this segue
guard let clickedButton = sender as? UIButton else {return}
//Now Simply assign this to nextVC
nextVC.button = clickedButton
}
}

How to programmatically seque to multiple view controllers from a button

I have a view controller with a lot (36) of buttons, and I want each of these buttons to segue to a particular view controller based on a variable that was set earlier in the program. In other words, any button could potentially go to 15 different view controllers based on a variable that was sent to the viewcontroller containing the buttons...
I think I can make this work if I click and drag each button to every viewcontroller... but it seems silly and messy.
I tried doing something like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if variable == "Whatever" {
let send = segue.destination as! AViewController
send.variablesent = (sender as! UIButton).title(for: .normal)!}
}
But this only works if I click and drag the button in the storyboard to the "AViewController".
Any help is appreciated, thanks!!
For that you can make segue from SourceViewController to DestinationViewController instead of from Button to Controller, After that when you call perfromSegue in your button action then pass button reference as sender in perfromSegue call.
#IBAction func buttonAction(_ sender: UIButton) {
self.performSegue(withIdentifier: "segueIdentifier", sender: sender)
}
Now in prepareForSegue cast sender to UIButton and set title according to it.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if variable == "Whatever" {
let send = segue.destination as! AViewController
if let button = sender as? UIButton {
send.variablesent = button.titleLabel?.text ?? "Default value"
}
}
}

How to identify if a scene has been opened by a certain segue in Swift?

I have a scene which I open with this segue.
//pass all retrived info from signup field over to the login scene to facilitate user experience
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showLoginController") {
let svc = segue.destinationViewController as! LoginController;
print("pass data over to next viewcontroller")
}
}
This segue goes back to the Login screen where I want to set some values. However when the Login screen has not been loaded by segue "showLoginController", some fields should be empty.
How can I identify if LoginScene has been opened by a certain segue and set values accordingly?
In your LoginController view controller add this:
var fromSegue = false
And in prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showLoginController") {
let svc = segue.destinationViewController as! LoginController;
svc.fromSegue = true
print("pass data over to next viewcontroller")
}
}
And then in your LoginController you can check fromSegue.
You can know the segue from the previous scene, in the sender scene, implement prepareForSegue() method to detect the sender