How to pass datasource to second View Controller? Swift - ios

So I have a dataModel that pulls Arrays from a plist using my datasource class. In my view controller I call the datasource class with
let dataSource = DataSource()
and then I grab values from the array with
abilities = dataSource.ability[monster.ability! + 2]
My issue is when I grab the Datasource from the second Viewcontroller, there is a 2-4 second delay during the segue transition. How can I pass the datasource over the second viewcontroller, so i can read the values, without having to call let dataSource = DataSource() from within the second view controller?

There are a few different ways to handle passing information from one view controller to another.
However for your scenario I would recommend to create an array property in your second view controller that will hold your Datasource, but only by passing it from your first view controller by calling the prepare(for segue: UIStoryboardSegue, sender: Any?) method.
Here is an example of how I passed simple data to another view controller, pretty much a Master-Detail setup:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationViewController = segue.destination as? DetailNoteViewController
if segue.identifier == "toNoteDetailView" {
guard let indexPath = tableView.indexPathForSelectedRow else { return }
let note = self.notes[indexPath.row]
destinationViewController?.note = note
}
}

Related

How to pass data from ViewControllers and show them into tableviewCell?

I want to pass data from my ViewController to TableViewCell, How can I do that. How to pass data from one ViewController and show them in TableViewCell.
The question is a bit too vague, but I will try. If you are using a segue from another viewController and the data is, for example, an array of Strings i.e in your first viewController:
var arrayOfStrings = ["StringRow1", "StringRow2"] // etc
and you want to be able to access this array when you enter a new viewController and use it for your tableView then you can use prepareForSegue
First, in your viewController with the tableView have a variable ready for the array:
var arrayOfStrings = [String]()
Then you can pass the data over like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueToTableView" {
if let vc = segue.destination as? YourTableViewController
{
vc.arrayOfStrings = self.arrayOfStrings
}
}
}
Now when you arrive in your tableView viewController, your arrayOfStrings data will be passed.
This is a basic simple example as you did not provide much context.
Creat variable in your cell class and in cell for row just assign that value to variable and use in your cell class.

Setting up delegates in container view

I have a container view in my Storyboard that displays another view controller that I already programmed and stuff. I want to communicate between the main View Controller and the contained-view controller. I know how to use delegates and I am comfortable with using them, however I normally set up delegates when I initialize a ViewController, however in this case I don't know where to apply this, since the view controller is already there per the storyboard. Normally I would do something like this:
class HomeVC: UIViewController {
func initializeVC() {
resultsVC = self.storyboard?.instantiateViewController(withIdentifier: "resultsView") as! GoalsVC
resultsVC.calcDelegate = self //I set the "HomeVC" as the Delegate since it has all the functions I need
}
}
As mentioned above, since I never really created this view controller via code, I don't know how to assign a delegate (specially setting the delegate to "self" (where Self is the main View Controller)
You can assign delegate in prepareforsegue. Like below code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "container_segue") {
let controller = segue.destination as! containerController
controller.delegate = self
}
}
When project runs, this method called automatically because we had created segue in the storyboard.
By using segue.identifier you can check for which controller segue is going to happen and accordingly you can achieve your requirement.
As you are using storyboard for container view. There is a segue with embed type. Give this segue a identifier, say MyContainedViewControllerSegueId
Then in prepare(for segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MyContainedViewControllerSegueId" {
// here you get your contained view controller as `segue.destination`
// cast it your subclassed view controller
// use delegate on that subclassed view controller for communication purpose.
}
}

iOS Swift - Data is not fetched quickly enough to reach another UIViewController

I have a source view controller and a destination view controller.
I would like to show data fetched from a url in the UI (destination) just after moving to this screen ("show" segue).
In order to do that, in the source VC I use "prepare for segue" method, where I call a function that returns an array with all the fetched data I want to show and pass it to the destination VC to be shown in a UITableView.
The problem is that many times the whole data is not fetched from the url, so I pass an empty array to the destination.
This is the code in the source VC:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVc = segue.destination as?
ShowCharacterInfoViewController{
fetchCharacterArrayFromUrl(characterName: cellContent){ results in
destinationVc.array.append(contentsOf:results)
destinationVc.tabelView.reloadData()}
} }
I can't think of a proper solution.
You can do one of two things.
Load the data and only perform the segue after the function has returned the data.
Transition to the destination screen and have that controller load the data in viewWillAppear.
// Add a place to save the results
var saveResults: MyResultsType?
#IBAction func someButtonAction(_ sender: Any) {
// Consider putting a "Loading..." dialog here
fetchCharacterArrayFromUrl(characterName: cellContent){ results in
self.saveResults = results
DispatchQueue.main.async({
// Hide the "Loading..." dialog
performSegue(withIdentifier: "ID of your Segue", sender: sender) //
})
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destinationVc = segue.destination as? ShowCharacterInfoViewController {
// I'm not sure append() is really what you need here
destinationVc.array.append(contentsOf: savedResults)
destinationVc.tabelView.reloadData()
}
}
You need to update the UI stuff in main thread since you are executing backend call:-
DispatchQueue.main.async({
destinationVc.tabelView.reloadData()
})

Updating TableView within containerview

I have my UIViewController, which is a person's profile page, it displays their name and picture. Within that UIViewController I have a UIContainerView that displays a static UITableView. I'm having a little trouble updating the cells of the table when the profile page loads. Here's my storyboard:
I have tried the following, within my UIViewController.
I created an outlet to my UIView and passed the person object to it.
In my UIView I called the segue to pass the object to the UITableViewController and from there I was going to update some labels.
func prepareForSegue(segue: UIStoryboardSegue!, sender: Any?){
if segue.identifier == "containerSegue"{
let statsTable = segue.destination as! CollectionTableViewController
statsTable.currentPerson = currentPerson
}
}
My Segue is never called though. I have moved it to the main UIViewController in case it should be called from there, but again not called. What am I doing wrong with this approach?
Assuming you have set the Segue Identifier to "containerSegue" you should get it in your "Stats" view controller.
Are you using Swift 3? It's possible you just have the func definition wrong:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "containerSegue" {
let statsTable = segue.destination as! CollectionTableViewController
statsTable.currentPerson = currentPerson
}
}
That should work.

Not able to push data from one view controller to a table view controller

I ran into a strange problem while I was working on my project. (Please bear with me, I'm a Swift beginner.)
This is what my storyboard looks like so far.
On the left is my regular view controller, and on the right is the TableViewController. the transition inbetween has a specific ID.
**This is the first View Controller.**
class TestsMenuViewController: UIViewController {
var tests = [Test]()
var testTableViewController : TestsTableViewController?
override func viewDidLoad() {
self.tests = DataModel().patientData
//this just populates the array with some data.
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "testTableTransition" {
testTableViewController = segue.destination as? TestsTableViewController
testTableViewController?.tests = self.tests
print(testTableViewController?.tests[0].testDescription)
//somehow this is an empty array
}
}
somehow the test array does not get passed to the next controller :( what am i doing wrong?
You could save the data as NSUserDefaults and call the saved data to the view when you want
Hey I managed to solve my problem, what I just did was initialize the data that I pass to the TableViewController directly in the attributes. Then it worked!

Resources