views:

440

answers:

2

I have a root UIViewController subclass that has a UITabBar, (I'm not using UITabBarController) and 5 tab bar items for 5 view controllers. Each view controller has a UIPickerView. Only one view controller is ever instantiated at a time -- when a tab bar item is selected, the current one is removed, the new one is instantiated and added, and the old one is deallocated (self.oldvc = nil;). So if the user goes to the 3rd row of the picker in the first tab, then switches to the second tab, then goes back, I want the 3rd row of the picker to be selected again. Currently, I have it so the view controllers are instantiated with a initWithSelectedRowOfFirstComponent:(NSInteger)firstRow secondComponent:(NSInteger).. etc., and then in my root view controller, (the oner with the tab bar), I have an ivar to cache each of the values.. But I'm not sure.. Is there a better way to do this? Maybe a plist file or a dictionary or something.. I don't know, what do you think the best way to do this would be? Thanks!!

I decided to use UITabBarController, let memory warnings deallocate and use a class I called "Model" which is a singleton (using this macro) to hold the data to use when the views get unloaded because of memory warnings.

A: 

Maybe you can keep an array of your pickers in your viewController and just create those once, before deallocating, you update your reference to the picker and during reinstantiation you set the picker from the array instead of making a new one.

Daniel
+1  A: 

If you don't want to keep all of the five view controllers allocated (in an array) you could separate the state of your views into a new class. You'd then keep 5 instances of that class around and write a function that can initialize your UIPickerViews from an instance of your new class.

Whenever the user selects a different tab, you pass a reference to the corresponding state object to the function that sets up your view. Also, all changes made to the state through the view should be directly applied to the model objects. Your root UIViewController acts as the main controller. See also: MVC Pattern.

Additional thoughts based on your comments...

I think you can try the following: Rather than creating and destroying your UIPickerView objects whenever a tab button is pressed, hold on to the objects. Have an "NSMutableArray *viewArray" in your main controller that holds all the views. I assume your root UIViewController is the delegate of the UITabBar. When you receive a tabBar:didSelectItem: message, you hide the current view and display the one corresponding to the selected item. Just iterate over the entire array and hide/unhide the item based on whether it corresponds to the selected tab bar item.

Basically this is a bit like starting to implement your own version of UITabBarController, so maybe you should consider using that.

VoidPointer
The view controllers aren't in an arrray, but anyway, could you explain a bit more how I could do this? It sounds like a good idea but I'm not really sure how to do it.
Mk12
So I should make a new class, just a plain NSObject sublclass, that contains the state of the controllers, and have one instance of that in my root controller?
Mk12
.. but the uipickers don't all have the same number of components, and one of them is a date picker, so how could one class be used for all of them?
Mk12
But the whole point of making my own UIViewController was to be more memory effiecient by only having one allocated at a time..
Mk12
Are you sure you are not optimizing prematurely? You might be sacrificing simplicity for unneeded optimizations.
VoidPointer