How to edit a UICollectionView item in another UIViewController? - ios

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

Related

Saving the state of the collection view when view controller is changed

I am using a collection view to present the data loaded from firebase. I am not using any sort of embedded navigation controller, just the normal viewcontroller.
Now, whenever I change my view and come back, all data is reloaded and the controller starts from scratch. I actually want it to be on the cell it was left of and how it was left.
I have check plenty of articles and sources on the internet, but most of them are about the embedded navigation controller.
Can anyone guide me on how exactly can I achieve this without using the embedded navigation controller?
Please let me know if anymore information is required. I'll be quite prompt.
I thinks it depends on where you reload your collection view data. You said
Now, whenever I change my view and come back
Did you present your next view controller or push view controller from view controller where your collection view exists? if yes, you may use dismiss or pop view controller to come back.
When you come back to view controller where your collection view exists, viewWillAppear and viewDidAppear method will be called.
Did you fetch data from firebase in one of these method? if yes all the data will be reloaded unless you made boolean flag not to load again.
Hope this help you.

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.

How to send back information from the detail view to master view

I have a master view with a tableview, then I go to the detail and modify it. what is the best practice to get the modify value, store it to my NSArray and update my tableview ?
I have made a delegate method in my detail view to call back my master view after modification, is it good? If you have a simple example with modify detail view.

TableView index from rootcontroller to detailcontroller (UINavigationController)

My root view is a grouped tableview. When the user selects a row, i want to be able to retain which row was selected to give to the detailcontroller for loading the correct data.
All the navigation is working fine, I just don't want to have to create a global variable to just retain the index. Is there a built in method for the navcontroller or something?
You can either set a property in you detail view controller before it is pushed giving info about the row selected so it can influence the behaviour of the detail view controller, or it is possible to access the parent view controller directly from the detail view controller with:
#property(nonatomic, readonly) UIViewController *parentViewController
I prefer the first option - you can write a custom init... method, to supply the data for the detail view controller when it's created.
There isn't a builtin way as such, you should try and make the view controllers de-coupled as possible so they can be re-used and are resistent to changes elsewhere in the app.
This is a useful quote from the View Controller Programming Guide for iOS:
With the exception of view controllers managing leaf data, each custom view controller must provide a way for the user to navigate to the next level of the data hierarchy. A view controller that displays a list of items can use taps in a given table cell to display the next level of data. For example, when a user selects a photo album from the top-level list, the Photos application creates a new photo album view controller. The new view controller is initialized with enough information about the album for it to present the relevant photos.
I wanted to follow up with how I ended up coding this. I'm still somewhat new to Obj-C, so some concepts I haven't dealt with or come across, so if this is old hat, sorry.
You can create your data element in the child controller and pass the data 1 for 1 directly to that element by accessing its property.
ParentController.h
NSDictionary *myData;
ChildController.h
NSDictionary *childData;
// This would get called in the parent controller where appropriate
// but before the child controller is presented
ChildController.childData = myData;
This is obviously very stripped down, but the idea works. Just take your data and pass it to the property before calling it and it will be there once the child view is presented. Hope this helps.

referencing UITableView to another tableview on a split view based app

I'd like to understand what's going on here. Basically I have a NumberOneViewController which owns a table view and is showing up on the details view controller on a split view based app.
When a user selects an entry on the NumberOneViewController tableview row, i assign the table view to RootViewController's tableView member like so:
self.tableView = numberOneViewController.tableView;
So the table view on the detail view controller is now gone - which brings me to my first question, what exactly happened here?
Now, I want number one view controller's table view again to show up on the details view controller, but how?
Maybe you need to reload/refresh the table view after you assign it. Just throwing out something off the top off my head since there are no other answers. Good Luck.

Resources