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

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.

Related

Swift - How to keep reference to old view controller when instantiating new view controller?

I am trying to programmatically instantiate a new view controller of the same type as my original view controller using this code:
self.navigationController!.pushViewController(self.storyboard!.instantiateViewControllerWithIdentifier(StoryboardKeys.ViewIdentifier), animated: true)
I would like the user to be able to go back to my original view controller, so I was wondering if there is a way to keep the old view controller in memory? Also if I instantiate a view controller this way, do I get to prepareforsegue (in order to programmatically add a back button)? If not, how could I add a back button when pushing this view controller?
I suspect there is a better way to do this, so if there is, please let me know. Thank you very much for any help!
UINavigationController maintain your view controllers as a stack automatically, so don't worry about your view controller's memory management.
Only if you want a custom back button, otherwise you don't have to add a back button by yourself, everything has been done.
Just use self.navigationController!.popViewControllerAnimated(true) somewhere in your second view controller . Navigation controller contains a stack of views that you can retrieve by using self.navigationController!.viewControllers. You can modify this stack as you like.

Possible to update a UIViewController that is not on screen?

I have a side menu controller that is part of the rootViewControllerI never remove it from there and when it slides off screen - its just an animation that updates its frame details.
Is it possible to update this view, while it is not displayed on scene? I have a UiTableView in there and I would like to reload it while it is off screen - so when the user slides out the screen, its already populated with new content.
My first approach was a delegate - however, the delegate method doesn't get fired and I believe this is due to it being off screen. But, I somehow think side its in UIWindow it is never really deallocated like a normal view when it leaves the screen?
Edit
I am using this Github project for the menu.
The view I want to update is in a UINavigation controller, one level deep. I can get the current instance of it - however, the delegate method doesn't trigger.
It seems to me that you are going with something like this. Even if not, look at the example. Here RootViewController is always alive and you move one viewcontroller to parent view controller and remove other one.
I have two ways to fix it:
If you are removing first view from parent view controller. Don't remove it. So the controller is still live and use delegates to trigger the event.
Remove first view controller then use Root view controller to get the updates and once the previous view controller loads back take updates from root view controller and update this one.
Hope it can atleast give you an idea.

How to store data after popping a storyboard instantiated view controller to then repush it to the navigation controller stack

I have my UIViewControllers mostly setup using a Storyboard file. In some cases I use the usual pattern of a UINavigationController in combination with UITableViewController to let the user dig into configuration details of the application. Each table view cell causes another view controller to be pushed onto the navigation stack (when the cell is selected) and users can go back to the overview table view controller using the navigation controller's back button.
I have the overview UITableViewController and the detail UIViewControllers set up in the Storyboard, including the connections between them using segues.
Most of it works as expected, when I select a table view cell in the overview the correct detail view controller is pushed onto the navigation stack. But if I then change some views in the detail view controller and go back (possibly because I want to look something up)(thus the detail view controller is popped) and then press the same cell again, the views are reset to their original state and the data I put in is lost.
Of course I could save that data in the overview controller when the detail controller is popped and restore it when it is pushed again, but I wonder whether that is the best way.
In the past, I would have constructed the detail view controller myself and stored it in an instance variable. Then, if I had to push it again, I would push the exact same object (not just an instance of the same class) which would mean that it also saved the state of the view.
But as far as I can tell, using Storyboards, for each segue a new view controller is instantiated, so no data is kept. I also cannot set the destinationViewController property of the segue in prepareforSegue:sender: since it is read-only.
Is there a way to reuse an already created view controller in a segue?
Or is there some other elegant way to store the data to reuse it when the detail controller is pushed again? Ideally something the overview table view controller does not have to know about, since it would have to do store the data for all detail view controller in that case.
I know I could retrieve the view controller from the storyboard, instantiate it myself and push it in tableView:didSelectRowAtIndexPath:, but I like the segues and the overview of the view structure the storyboard provides, so I would like to keep that, if possible.
Update:
I think my description was a bit unclear. I do save the data, already, but currently it is saved in the detail view controller (it's not just "saved" by being in the view, I am not trying to abuse the view to store my data), so going back is an implicit "save my current state in this view" in my case. The problem is, I can't implement that in an easy way without storing the data in the overview controller IN ADDITION to storing it in the detail view controller. And I don't want to store it in the overview controller since it is data that belongs to the detail view controller and should be managed by it.
Of course I could save that data in the overview controller when the detail controller is popped and restore it when it is pushed again, but I wonder whether that is the best way.
I think that is the best way. If the detail view controller is being used to edit the data, generally accepted practice is that the user can only leave it by either saving the data or canceling their changes.

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.

issue modally presenting a table view controller that has a search display controller and returning the selected cell

in my iOS application, i'm wanting to present the user a table of items using a UITableViewController, have them select an item, then return that item back to the another view controller. i can do this successfully by defining a protocol and delegate method for the table view controller, presenting the table view controller modally, then dismissing it when the user selects an item and returning the item to the delegate view controller. but, if i also implement a search display controller for the table view (so the user can search for a specific item in a longer list) i run into a memory issue. i've modified apple's 'TableSearch' example to demonstrate this, and have posted the code at https://github.com/pistachionut/Table-Search-Example
in short, the app usually crashes with an EXC_BAD_ACCESS just after selecting a cell in the table view. running it with NSZombieEnabled is indicating that the table view controller is being called by -[UISearchDisplayController _destroyManagedTableView] after its retain count has reached 0. anyone have an idea why this is happening? i don't think i'm doing any additional releasing of the table view controller beyond what i'm responsible for. i create it using alloc and initWithNibName, present it modally, then imediately release it (see -(IBAction)showProductPicker:(id)sender in the 'PickProductViewController.m' file in my example). thanks!
the answer posted by Jeff to How can UISearchDisplayController autorelease cause crash in a different view controller? solves the problem.

Resources