I recently started exploring MVVM and stuck at passing data between 2 view controllers.I have an array of items in my viewModel1 of ViewController1 and I want to pass that array to viewcontroller2. I am able to achieve it by getting the whole array from viewModel1 like below but I am not sure if this is the right way to do it.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == Constants.kShowDetailSegue {
let destinationViewController = segue.destination as! ListViewController
destinationViewController.products = viewModel1.getFavouriteProducts()
//the getFavouriteProducts gets data from coredata.
}
}
I think you have done it the right way, but alternatively you can use closures. Which are the preferred, method of communication within iOS. You will take care of memory leaks wherever necessary by using
weak
OR
unowned
Related
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.
I have a masterViewcontroller with the container on it and a 2ndViewController embeded via storyboard in that. I am wondering how to access the 2ndViewController from the masterViewController.
I have seen about using prepare for segue but this doesn't seem to get called for when my viewController in the container is shown. Is there something I need to hook up for it to appear in the prepare for segue function?
Or is there another way to achieve this?
You need to override prepare(for segue: sender:) in the masterViewController class.
The segue needs an identifier in the storyboard. In prepare, you then check if the segue to be prepared for is the one you gave the identifier to via segue.identifier == "yourIdentifier".
Then you can resolve the embedded ViewController as your 2ndViewController like so:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "yourIdentifier" {
let child = segue.destination as! 2ndViewController
}
}
By the way, if you use as!, you're force-unwrapping segue.destination as your 2ndViewController class. If you're not 100% certain this segue will always have that class as it's destination, consider instead using as? to treat child as optional and then doing additional checks for it's existence before attempting to use it.
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
}
}
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!
I am trying to pass an Array Object between 2 view controllers. But I want the Array to be passed as a Reference and not copied. I know if I was using a function locally, I can use "inout" and "&" based on the examples I found.
But I what I want to do is slightly different. I want to assign the Array in VC1 directly to the Array object in VC2 as a reference. Here is my code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "vc2" {
let vc2 = segue.destinationViewController as! ProfileVC
vc2.data = &self.data //I know this line doesn't work, how would I go about it?
}
}
Swift array are struct, so they will get copied.
The simplest way would be to use an object instead of a struct. So I would use a NSMutableArray instead.
With that you will have all the power of mutability at your finger tips ;-)