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
Related
I am trying to use segues to pass the data entered in the partyID text field to the partyID label in a separate view controller. However, I am getting errors in my code.
class PartyViewController: UIViewController {
// CALLS LOGIN VC
var LoginViewController: LoginViewController?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var partyID: UITextField!
var token = String()
#IBAction func startParty(_ sender: UIButton) {
self.performSegue(withIdentifier: "partyVCtoGuestPartyVC", sender: self)
performSegue(withIdentifier: "hostStartParty", sender: self)
//LoginViewController?.fetchSpotifyProfile(accessToken )
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "partyVCtoGuestPartyVC"){
let GuestPartyVC = segue.destination as! GuestPartyViewController
GuestPartyVC.partyID = partyID.text
}
And here is the view controller I am trying to pass the data to:
class GuestPartyViewController: UIViewController {
#IBOutlet weak var partyID: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
partyIDLabel.text = partyID
// Do any additional setup after loading the view.
}
I get errors in my override func in LoginVC and then in the partyIDlabel.text in the GuestPartyVC.
In GuestPartyViewController
class GuestPartyViewController: UIViewController {
#IBOutlet weak var partyIDLabel: UILabel!
var partyID: String?
override func viewDidLoad() {
super.viewDidLoad()
partyIDLabel.text = partyID ?? ""
}
}
In PartyViewController
class PartyViewController: UIViewController {
#IBOutlet weak var partyID: UITextField!
#IBAction func startParty(_ sender: UIButton) {
self.performSegue(withIdentifier: "partyVCtoGuestPartyVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "partyVCtoGuestPartyVC",
let GuestPartyVC = segue.destination as? GuestPartyViewController {
GuestPartyVC.partyID = partyID.text
}
}
}
The IBOutlet is weak and may not be instantiate when you pass the text.
Could you try to pass the text in a property, then assign it in the viewDidLoad ?
class GuestPartyViewController: UIViewController {
#IBOutlet weak var partyID: UILabel!
var passedText: String?
override func viewDidLoad() {
super.viewDidLoad()
if let unwrappedPassedText = passedText {
partyIDLabel.text = partyID
}
}
// In the other controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "partyVCtoGuestPartyVC") {
let GuestPartyVC = segue.destination as! GuestPartyViewController
GuestPartyVC.passedText = partyID.text
}
first change the call of login VC
var LoginViewController = LoginViewController()
then put this before the view did load method
#IBOutlet weak var partyID: UITextField!
and can you send the error that you get
I am new to Swift and was wondering on how to pass data from ViewController to ViewController that isn’t connected by segue. I have spend 2 hours on this and still can’t figure a way to do it.
Edit: The problem that I am confused on is How to take out all the stacked ViewController expect the root ViewController while being able to pass data back to the first ViewController from ViewController3 with
'navigationController?.popToRootViewController(animated: false)'
class ViewController: UIViewController, nameDelegate {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var textfield1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
label1.text = "Name"
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc2 = segue.destination as! ViewController2
vc2.middleOfTransferingName = textfield1.text!
}
#IBAction func buttonPressed1(_ sender: Any) {
performSegue(withIdentifier: "go2", sender: self)
}
func nameThatWasEntered(name: String) {
label1.text = name
}
}
class ViewController2: UIViewController, nameDelegate {
var middleOfTransferingName: String = ""
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc3 = segue.destination as! ViewController3
vc3.transferedWithSegueLabelText = middleOfTransferingName
vc3.namePassBack = self
}
#IBAction func buttonPressed2(_ sender: Any) {
performSegue(withIdentifier: "go3", sender: self)
}
func nameThatWasEntered(name: String) {
}
}
protocol nameDelegate {
func nameThatWasEntered(name: String)
}
class ViewController3: UIViewController {
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var textfield3: UITextField!
var transferedWithSegueLabelText: String = ""
var namePassBack: nameDelegate?
override func viewDidLoad() {
super.viewDidLoad()
label3.text = transferedWithSegueLabelText
}
#IBAction func buttonPressed3(_ sender: Any) {
namePassBack!.nameThatWasEntered(name: textfield3.text!)
navigationController?.popToRootViewController(animated: false)
}
}
I found the way to transfer ViewController3 data to ViewController!
var vc3 = ViewController3()
then making ViewController as the delegate of vc3 upon loading.
override func viewDidLoad() {
super.viewDidLoad()
vc3.namePassBack = self
}
Then going back to ViewController3, I add ""vc3."" before using the delegate.
#IBAction func buttonPressed3(_ sender: Any) {
vc3.namePassBack!.nameThatWasEntered(name: textfield3.text!)
navigationController?.popToRootViewController(animated: false)
}
if you use segue then use 'Unwind segue'
for this write given code in your 'A view controller'
#IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}
In B_viewcontroller, On press button call 'Unwind segue'.
Note:- With the help of Unwind segue you can send the value for 3ed vc to 1se vc same as you send value form 1st vc to 2nd vc
for more go to this link
So how i transfer my ViewController label: totalPar to ThirdViewController label: totalPar5. And I want to transfer data that I have added there with my minus and plus buttons
Here is simulator pic that show what I want to transfer
My ThirdViewController is almost same as ViewController except prepare segue
Here is my ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var totalPar: UILabel!
#IBOutlet weak var plusminusPar: UILabel!
#IBOutlet weak var currentPar: UILabel!
var totalPAR = Int()
var plusminusPAR = 0
var currentPAR = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func minusButton(_ sender: Any) {
totalPAR = Int(totalPar.text!)!
self.totalPar.text = String(totalPAR - 1)
plusminusPAR = Int(plusminusPar.text!)!
self.plusminusPar.text = String(plusminusPAR - 1)
currentPAR = Int(currentPar.text!)!
self.currentPar.text = String(currentPAR - 1)
}
#IBAction func plusButton(_ sender: Any) {
totalPAR = Int(totalPar.text!)!
self.totalPar.text = String(totalPAR + 1)
plusminusPAR = Int(plusminusPar.text!)!
self.plusminusPar.text = String(plusminusPAR + 1)
currentPAR = Int(currentPar.text!)!
self.currentPar.text = String(currentPAR + 1)
}
#IBAction func Seuraava(_ sender: Any) {
self.performSegue(withIdentifier: "next1", sender: Any?.self)
}
#IBAction func seiraava2(_ sender: Any) {
self.performSegue(withIdentifier: "seuraava2", sender: Any?.self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let thirdviewcontroller = segue.destination as! ThirdViewController
thirdviewcontroller.totalPAR5 = self.totalPAR
}
}
From the accepted answer and its comments you need to start improving your code and learn some concepts of data source in general.
For your case stop constantly converting string to integers to string. Choose one or the other:
class ViewController: UIViewController {
var totalPAR: Int = 0
var plusminusPAR: Int = 0
var currentPAR: Int = 0
Do natural operations on actions and separate methods:
#IBAction func minusButton(_ sender: Any) {
addToAll(valueToAdd: -1)
refreshLabels()
}
private func addToAll(valueToAdd: Int) {
totalPAR += valueToAdd
plusminusPAR += valueToAdd
currentPAR += valueToAdd
}
private func refreshLabels() {
self.totalPar.text = String(totalPAR)
self.plusminusPar.text = String(plusminusPAR)
self.currentPar.text = String(currentPAR)
}
Then you will have no issues calling
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let thirdviewcontroller = segue.destination as? ThirdViewController {
thirdviewcontroller.totalPAR = self.totalPAR
thirdviewcontroller.plusminusPAR = self.plusminusPAR
thirdviewcontroller.currentPAR = self.currentPAR
}
}
Now if in both view controllers you call refreshLabels on viewDidLoad the values are successfully transferred.
Simply make the variable in ThirdViewController and assign the value in prepare for segua and setup value to the label in viewDidLoad:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let thirdviewcontroller = segue.destination as! ThirdViewController
thirdviewcontroller.totalPAR5 = self.totalPAR
}
class ThirdViewController: UIViewController {
var totalPAR5 = 0
override func viewDidLoad() {
super.viewDidLoad()
self.totalPar.text = "\(totalPAR5+1)" //You can calculate here like +1 or -1
// Do any additional setup after loading the view.
}
}
I have created a Calculator using Swift in Xcode. I would like to add another functionality to it, I already have a history label that displays the previous calculations. I would like to pass the data that displays in that history label into a TableViewController and for each calculation my history label shows to have it add each data into my TableViewController. I know I should be able to use perform segue, but I'm not exactly sure. Here is my code so far:
ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var displayLabel: UILabel!
#IBOutlet weak var HistoryLabel: UILabel!
var userIsTypingNumbers = false
#IBAction private func NumbersEntered(_ sender: UIButton) {
//know what number is being pressed
let digit = sender.currentTitle!
//if user is typing a number, do this.
if userIsTypingNumbers{
//specify what number is being pressed
let textCurrentDisplay = displayLabel.text!
//append the another number onto the previous number.
displayLabel.text = textCurrentDisplay + digit
} else {
displayLabel.text = digit
}
userIsTypingNumbers = true
}
var displayValue: Double {
get {
return Double(displayLabel.text!)!
}
set {
displayLabel.text = String(newValue)
}
}
private var calculations = PerformCalculations()
#IBAction func Enter(_ sender: UIButton) {
//perform the calculations
if userIsTypingNumbers{
calculations.setOperand(operand: displayValue)
userIsTypingNumbers = false
}
if let mathematicalSymbol = sender.currentTitle {
calculations.performOperation(symbol: mathematicalSymbol)
}
HistoryLabel.text = HistoryLabel.text! + String(sender.currentTitle!);displayValue = calculations.result
HistoryLabel.text = HistoryLabel.text! + String(displayValue)
}
#IBAction func Clear(_ sender: UIButton) {
//clear display to 0.
displayLabel.text = "0"
HistoryLabel.text = ""
}
#IBAction func Delete(_ sender: UIButton) {
//deleting last typed number, if user messed up.
let name: String = self.displayLabel.text!
//count number of characters.
let stringLength = name.characters.count
let substringIndex = stringLength - 1
displayLabel.text = (name as NSString).substring(to: substringIndex)
}
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.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "History"){
if let destinationVC = segue.destination as? HistoryClassViewController{
destinationVC
}
}
}
}
I have started attempting a prepare for segue function, but not sure how to make it work. Any help would be much appreciated. Hopefully this makes sense. Here is a picture of how my Calculator is laid out in Xcode:
Create in your HistoryClassViewController field like
var someData: Any!
Then:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "History" {
if let destinationVC = segue.destination as! HistoryClassViewController {
destinationVC.someData = something
}
}
}
Then to perform segue in place you wants to type this:
self.performSegue(withIdentifier: "History", sender: self)
Hope it helps
Here is thing Take one String Variable as global Variable in HistoryClassViewController class
example:
class HistoryClassViewController: UITableViewController{
var dataString:String!
//............Continue code
//............
Now Write this Method in ViewController class
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "History"){
if let destinationVC = segue.destination as? HistoryClassViewController{
destinationVC.dataString = displayLabel.text!
}
}
}
Finally access dataString value in TableViewController.
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
}
}