data erased reappear when i pressed the back button Swift 3 - uitableview

I have 2 views and a navigationController. The first, adds data in an array. This datas are displayed in my second view (is a tableviewController). I can erase some data in my array directly from my tableView, and I remove a row at the same time.
When I pressed the back button, and I try to add a new data, when my second view appear, I see my data news datas, and the data erased... I don't understand.
From the view 1 to view 2, I have the "prepare(for segue: UIStoryboardSegue, sender: Any?)" function.
Any help would be appreciated.

This is normal.
Let's say you have an array called data in the first view controller, and you pass this array to the second view controller when navigating to it. When you pass this array, it gets copied. The data array in second view controller is an array different from data array in first view controller.
So changes applied to data array of the second view controllers do not affect data array of first view controller.
To make these changes make effect on first view controller you need to change data array of first view controller somehow; you can use delegates or callbacks for example.

Related

How to get the data from one view controller class into another one to display in a TableView

I am a beginner at Swift. I have two viewControllers: 1 of them has a button which I =linked to another view Controller which contains a tableView. I want to get the array of URL strings from the first view controller to display in a TableView in the second view controller and update while the user is browsing using WebKit View. How can I do this in Swift.

How to get current view from Page View Controller

I understand that with my page control I can get the current view controller with "pageControl.currentPage".
Let's say I have a total of 3 view controllers, but the second view controller is being re-used.
So the order is [1stViewController, 2ndViewController, 2ndViewController]
From 2ndViewController, how can I determine if it's the 1st or 2nd index in the order?
I would like to be able to check in the viewDidLoad method before I update the UI of the view controller.
Check out this little project I threw together:
https://github.com/PJayRushton/PageViewControllerReferences
Basically I just created an array of view controllers used in the PageViewController DataSource and in the reused ViewController I check which view controller from the stored array it is.

How to edit a UICollectionView item in another UIViewController?

I'm using a Master Detail View Controller with Swift.
When I click on a master cell, I see a collection view containing a list of pictures.
Each picture represent data stored inside Core Data.
Each picture data has also a timestamp and all picture taken the same day are stored in the same Master cell.
[Date of the day 1]
[pic1]
[pic2]
[Date of the day 2]
[pic3]
[pic4]
What I want to achieve is:
When I click on a picture, another ViewController is displayed (through a segue) and this new VC allows me to edit the picture and change its date.
The thing is I have multiple things happening here when I change the day or a picture:
if the pic was alone in the collection, then I also have to remove the Master Day cell too.
if the pic was not alone, I just need to update the detail collection view
In any cases, if I have to create a new Day, I need to create a new Master Cell and update the view and if I need to delete a Day, I have to also update the Master view.
If you edit the collection items, you can simply do a:
self.collectionView performBatchUpdates:
and then update the model, and notify the collection view of your action...
but I don't see how I can do that from another UIViewController.
Currently, in the Edit View Controller, I update the model and then dismiss the View controller. And I get a crash because the collectionView tries to display an Item that is not part of the current collection anymore...
To solve this issue, maybe I can use a protocol in order to inform the detail view from the edit view but If I do that, I need to give the IndexPath of the Edit Cell to the edit view and then give it back to the detail view through the protocol... Why not. but not that clean in my opinion.
Another problem is, the app seems to also crash in the master view when I delete a Day. Because, the master view doesn't know that I deleted a day from the edit view.
My main problem is that I don't see how to tell my Master View Controller that I made some model changes... especially when I don't have any IndexPath information from within the edit view.
Technically, I could use the notificationCenter to notify both Views, I guess... but still, I would need to pass both IndexPath from the Master view to the Detail view and then to the Edit view.
Ugly.
Several ways by which this can be achieved:
1) Delegation: The view controller containing collection view will act as a delegate of Edit View Controller and when editing is done it will callback a method to 'The view controller containing collection view'
2) Notification: EditingFinished
3) blocks
Using protocol is good solution but can be painful since you have to manage edited items using their indexPaths. A simpler solution, since you are using CoreData, is to fetch entries using a computed property and just call collectionView.reloadData() on viewWillAppear method from the controller that contains collectionView. This way calling reload data will recompute Core Data entries and will place each item in correct position. Also viewWillAppear will get called after dismissing controller that stands on top of collection view controller
I found an interesting article addressing my problem.
It was not indeed a trivial problem...
http://www.objc.io/issues/4-core-data/full-core-data-application/#using-a-collection-view

Executing Event on Unwind Segue

I'm not sure if I explained this correctly in my question, so I'll explain it here. Please excuse my iOS illiteracy, complete newbie here.
The master view controller is a UITableViewController that holds a list of items. So, each cell contains an item. This list is populated from a Core Data model.
If I want to add an item, there's an Add button that takes me to a different view controller that has a text field. I write the item name in the text field, press the Done button and it adds it to Core Data, and unwinds back to the UITableViewController.
I want the table view to reload its data as soon as the unwind happens, so the user sees that his item has been entered into the list. I have to use a refresh control in order for the table to reload its data.
Is there a method whose code runs once the part written in bold happens?
Thanks in advance.
You can reload your table view data in the viewWillAppear method of the UITableViewController, which is called every time your view appears on screen. You can see this question for more details on the view controller lifecycle.

Dismissing a view makes losing it all values... viewWillAppear as a cure?

I have a basic modal view system.
My app loads the UI base in which there are 2 buttons presenting 2 other views.
In those views, a dismiss button.
Everything works fine.
BUT, in one of the 2 modal views, I have a bunch of UISlider & UISwitch.
I want them to retain their values but the dismiss loses them: as soon as I trigger the button to show the view containing the UI elements, this view is shown with all values for all elements as I put initially in the xib.
should I store all values in variables, then in viewWillAppear I could "recall" them ?
would you advice me another strategy ?
Yes, your proposed approach is exactly the right sort of thing. But be careful; viewWillAppear can be called for many reasons; make sure you're only doing this when the view controller is coming into existence and showing the view for the first time.
NSUserDefaults can be an excellent place to store globally needed info like this. In viewWillDisappear, store the desired state info (values of the sliders and switches) in defaults. Then retrieve them the next time the view is about to appear.
When you create the modal view you are creating a new instance of the modalViewController an the modalView. This new instance knows nothing about any other instance. There are a few ways you can retain the information from previous iterations of these modal view controllers.
How I would do it:
Set up place holders in your main view and pass the values that the user selects back to the main view via a protocol and delegate setup. Then when you segue to the modal view you can load those variables in before displaying the modal view.
So let's say you have a dictionary with all of the values: {slider = YES, someValue=10,...} Create that dictionary in the main view controller, the first one that opens, and place some default values in it.
In your modal view controllers create the same dictionary as a property.
Create a protocol in your modal view controller with a method that is something like
- (void) doneEditing:(NSDictionary *)values
Set up your first view as the delegate for the modal view controller and in the implementation of doneEditing copy the values to the dictionary that is present in the first view before popping the modal view.
When the first view is ready to present the modal view again, copy the values to the dictionary property of the modal view before presenting it.
I hope this gets you headed in the right direction. It's important to remember that each time you segue or create and present a modal view you are creating a brand new instance of that view, it knows nothing about the previous instance at all unless you tell it something about it.

Resources