Passing data from a JSON array to another view controller - ios

I'm trying to pass data from one view controller such as the name and trying to display it in the next view controller but I'm not sure how to do it. I'm using this API which is a JSON array to get the data for my app. I've looked all over for the answer to this but everything I try doesn't work. This is the code I'm using to try it right now but it doesn't work, this is in the first view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {`
if segue.identifier == "nextView" {
if let name = sender as? String, let nextView = segue.destination as? ListViewController {
nextView.nameText = name
}
}
}
This is the code in the destination view controller
class ListViewController: UIViewController {
#IBOutlet weak var name: UILabel!
var nameText: String = ""
override func viewDidLoad() {
super.viewDidLoad()
name?.text = nameText
}
}

The var you are trying to set in prepare nameText is a String so you should send it a String and not a [jsonList]
try like this :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "view" {
if let name = sender as? [jsonList], let nextView = segue.destination as! ListViewController {
nextView.nameText = //change affectation here
}
}
}

Related

Trouble passing int data from one view controller to another (segue) [duplicate]

This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 3 years ago.
I would like to pass an int data from one view controller to another one.
The problem is that the int data received in the second view controller doesn't match the first view controller's int data.
View controller 1:
import UIKit
class levelsSelector: UIViewController {
var levelSelected: Int = 0
var gameWanted: Int = 0
#IBAction func level1Tapped(_ sender: Any) {
gameWanted = 1
performSegue(withIdentifier: "gameOn", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "gameOne" {
let levelsSelector = segue.destination as! game
levelsSelector.finalGame = levelSelected
let levelsSelector2 = segue.destination as! game
levelsSelector2.finalLevel = gameWanted
}
}
}
View controller 2:
import UIKit
class game: UIViewController {
var finalLevel: Int = 0
var finalGame: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
print(finalLevel)
print(finalGame)
}
}
You've made a typo in your segue name
performSegue(withIdentifier: "gameOn", sender: self)
...
if segue.identifier == "gameOne" {
these two identifiers need to match
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? game {
destination.finalGame = levelSelected
destination.finalLevel = gameWanted
}
Also, check: your seque identifier on a storyboard should match a string in: perform segue method

Swift - Pass data from parent view controller to child view controller

My goal is to retrieve my eventId from my parent view controller to the child controller. But it seems that my child view controller is being instantiated before the parent. How can I get that eventId from my child controller? Thank you
I'm passing data from my EventsMainController to EventsDetails(Parent Controller)
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "eventDetails" {
let DestViewController : EventDetailsViewController = segue.destination as! EventDetailsViewController
DestViewController.eventId = myEvents[index].uuid
}
}
Then in my EventsDetail Controller I have my variable where I can retrieve it. EventsDetails is my parent controller where I have my child controller in it.
var eventId = String()
In my child controller I'm using this to retrieve the id. It's returning nil.
var eventId = String()
override func viewDidAppear(_ animated: Bool) {
print(eventId)
}
When you add a Container View in storyboard it adds a child view controller and a segue from the parent view controller to child view controller.
This segue is performed immediately after the parent view controller is loaded. Pass the data from EventDetails to InvitedController in prepare for segue method
class EventsMainController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "EventDetails" {
if let eventDetails = segue.destination as? EventDetails {
eventDetails.eventId = "FromEventsMainController"
}
}
}
}
class EventDetails: UIViewController {
var eventId = String()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "InvitedController" {
if let invitedController = segue.destination as? InvitedController {
invitedController.eventId = self.eventId
}
}
}
}
class InvitedController: UIViewController {
var eventId = String()
override func viewDidLoad() {
super.viewDidLoad()
print(eventId)//FromEventsMainController
}
}

pass data from view controller to tabbarviewcontroller

I am segueing from a view controller to a tabbarcontroller and I want to pass data. I want to pass "sendAuthor" to the first view controller of the tabbarcontroller.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FirstVC" {
let vc = (segue.destination as? UITabBarController)?.viewControllers?.first as? CommentProfileViewController
vc?.sendAuthor = sendAuthor!
vc?.Username.text = sendAuthor!
print(sendAuthor!)
}
}
In order to make sure I am getting the right thing, I included a print statement print(sendAuthor!) and I am getting the correct print statement. I also included a print statement in the destination view controller but the print statement returns nil
var sendAuthor: String?
override func viewDidLoad() {
super.viewDidLoad()
print(self.sendAuthor)
}
Your VC is imbedded in a UINavigationController. You need to take that into account as well:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FirstVC" {
guard let tabbar = segue.destination as? UITabBarController,
let navcon = tabbar.viewControllers?.first as? UINavigationController,
let vc = navcon.topViewController as? CommentProfileViewController
else { return }
vc.sendAuthor = sendAuthor!
vc.Username.text = sendAuthor!
print(sendAuthor!)
}
}

How can I use one var or let from a view controller to another view controller

I made a popup view controller but now I'm trying to pass the data from the popup to the view controller via prepare function. Let's take a look.
// this is from the pop up view controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let toBeMoved :ViewController = segue.destination as! ViewController
toBeMoved.enterVC()
amountEntered.text = "\(runningNumber1)"
}
// and I added a func in my main VC but I can't get the var in the VC
// totalCash is a label to be changed when the amount is entered from the
// pop up vc
func enterVC () {
totalCash.text = "\(amountEntered)"
}
I added enterVC to viewDidLoad.
Try this and see:
class TestVC: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let toBeMoved :ViewController = segue.destination as! ViewController
toBeMoved.amountEntered = runningNumber1
toBeMoved.enterVC()
}
}
class ViewController: UIViewController {
var amountEntered: Int = 0
func enterVC () {
totalCash.text = "\(amountEntered)"
}
}
or try this also.
class TestVC: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let toBeMoved :ViewController = segue.destination as! ViewController
toBeMoved.enterVC(amountEntered: runningNumber1)
}
}
class ViewController: UIViewController {
func enterVC (amountEntered: Int) {
totalCash.text = "\(amountEntered)"
}
}
//Turns out I needed to put a guard let in order to make this work also added IBAction in the original view controller like so:
class ViewController : UIViewController {
#IBAction func didUnwindSegue (sender: UIStoryboardSegue){
guard let realVC = sender.source as? ViewController else {
return
}
}
}
class TestVC : UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let realVC = segue.destination as? ViewController else {
return
}
realVC.totalCash.text = runningNumber1
}
}

Pass data from the first VC to the third (Swift)

I have 3 viewControllers and i'm passing data from the first to the second in this way (this is the first VC)
var steppers : UIStepper?
#IBOutlet weak var hourLabel: UILabel!
#IBOutlet weak var stepper: UIStepper!
#IBAction func stepper(_ sender: UIStepper) {
hourLabel.text = String(sender.value)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nc = segue.destination as? SelectClass {
nc.limit = Int(stepper.value)
} }
in the second VC i have the var limit = 0. Till here everything works well but what i want to do is to pass the value that the user gives to the stepper to the third VC. I tried to create another variable in the third VC var limit2 = 0and to pass the data in this way from the secondo VC to the third
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? ThirdClass {
vc.limit2 = limit
} }
but without results, my var limit2 = 0it always has the value 0 instead of taking the value that i added with the stepper. How can i do?
this is the prepare in the second VC
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == nearbySearchSegueIdentifier {
guard let category = sender as? QCategoryy else {
return
}
if let selectedRows = tableView.indexPathsForSelectedRows {
if let vc = segue.destination as? ThirdClass {
vc.category = category
vc.limit2 = limit
}
}
}
}
Considering your current code, its possible that limit2 its not set because this condition is not valid:
// This condition could be failing sometimes
if let selectedRows = tableView.indexPathsForSelectedRows {
if let vc = segue.destination as? ThirdClass {
vc.category = category
vc.limit2 = limit
}
}
According to the Documentation, indexPathsForSelectedRows returns an optional and in your segue, you are only setting limit2 if that value is not nil.
Try to set limit2 outside any condition, so it will be executed always and if you need to fulfill a condition in order to do a segue, check shouldPerformSegue(withIdentifier:sender:) here.
Also, if the value that you need on VC3 is the same that you have when you leave VC1, there are different approaches that you could use to pass the data between them without having to rely on VC2.
One could be to create a static variable in VC1 and set the limit value before pushing to VC2:
var steppers : UIStepper?
#IBOutlet weak var hourLabel: UILabel!
#IBOutlet weak var stepper: UIStepper!
// ADD THIS
static var globalLimit: Int = 0
#IBAction func stepper(_ sender: UIStepper) {
hourLabel.text = String(sender.value)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let nc = segue.destination as? SelectClass {
nc.limit = Int(stepper.value)
// AND THIS
VC1ClassName.globalLimit = Int(stepper.value)
}
}
Then inside VC3 load your global value whenever you want (maybe viewDidLoad):
override func viewDidLoad() {
super.viewDidLoad()
limit2 = VC1ClassName.globalLimit
}
Instead of having data passing through ViewControllers, you could also create a StepperManager class or something similar that is responsible for managing the data and you can access it from every class you need at any moment in time.
Why don't you just pass if from First to Second to Third?
FirstVC:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "tosecondsegue" {
let itemController : Second = segue.destination as! Second
itemController.limit = 0 //Whatever you want
}
}
SecondVC:
var limit = 0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "tothirdsegue" {
let itemController : ThirdVC = segue.destination as! ThirdVC
itemController.limit2 = limit
}
}
ThirdVC:
var limit2 = 0
//Use it here now

Resources