QUICK BACKGROUND:
I have an app that shows a list of songs in a searchable, tabbed interface (a.k.a. "Cheers View Controller"). There are two tabs, one for each category of my cheers. I have a sidebar that allows you to select menu options, one of which is called "My Favorites". It uses the SWReveal Controller (a.k.a. "Sidebar"). I am trying to allow the user to mark favorite cheers before game time, then use the sidebar navigation to quickly reference their list of favorite songs when they're in the dugout.
The initial view controller for my application is a Reveal View Controller.
The front view (sw_front) is the tab bar controller that shows the Cheers View Controller when the app first launches. The data is loaded into an array form a CSV file in the ViewDidLoad of the Cheers View Controller.
The rear controller (sw_rear) is the Sidebar that defines the menu options for my application. One of the menu options on my Sidebar is called My Favorites. It's this sidebar that is conceptually throwing me. See below for a snapshot of the relevant area of my storyboard.
STORYBOARD SNAPSHOT: It turns out that as a new user I cannot post images. :(
GOAL
I am trying to access the array of favorite cheers in the Cheers View Controller from the My Favorites view controller. There is currently no segue from Cheers View Controller to My Favorites and it seems like defining a segue here is wrong conceptually.
I don't want to use a singleton or some other work around, I would rather structure my app the correct way. One easy solution is to move My Favorites over to another tab of the Tab Bar Controller. While I can change the design and things would probably be easier, it feel like I'm missing a valuable concept here that I can use in later apps.
I realize that there are many posts already on the topic of passing data from one controller to another. I've read what I think is all of them but I have not been able to incorporate the solutions into the SWRevealController implementation successfully yet. So clearly I'm confused either on mechanics or on concepts (or both). Most of those posts I read were involving segues or passing fields between two controllers that had segues or relationships of some sort.
MECHANICS QUESTIONS:
I currently prep the favorites array in the ViewDidLoad of the table view controller in the Main Tabbed Interface. I did this immediately after loading the main array with all the songs from a CSV file. I was thinking that I could somehow pass this to the My Favorites table view controller or access it from the My Favorites Table view controller.
//Copy favorite cheers into array
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.favorite contains[c] %@",@"Yes"];
NSArray *tempArray = [self.cheersArray filteredArrayUsingPredicate:predicate];
self.myFavoriteCheersArray = [NSMutableArray arrayWithArray:tempArray];
Here's where it gets sticky for me - when the user clicks the button to show the SideBar, then clicks on My Favorites:
the prepareForSegue of the Sidebar will execute with this:
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
// Get the selected row and identify the destination controller you are sending to
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
UINavigationController *destViewController = (UINavigationController*)segue.destinationViewController;
// Set the title of navigation bar by using the menu items
destViewController.title = [[_menuItems objectAtIndex:indexPath.row] capitalizedString];
if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;
swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {
UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
[navController setViewControllers: @[dvc] animated: NO ];
[self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
};
}
And I was trying to add this to the end of the prepareForSegue to somehow allow My Favorites access to the array...but I'm having trouble identifying the property in the Cheers View Controller from the Sidebar...
if([segue.identifier isEqualToString:@"myFavorites"]) {
//Get the Favorites View Controller (which has a navigation controller)
MyFavoritesViewController *myFavoritesViewController = [[MyFavoritesViewController alloc] init];
myFavoritesViewController = (MyFavoritesViewController*)destViewController.topViewController;
//THIS BELOW PART IS SHAKEY AT BEST
//Get the Cheers View Controller (which is part of a tabbed view controller)
SWRevealViewController *frontViewController = [[SWRevealViewController alloc] init];
CheersViewController *cheersViewController = (CheersViewController*)frontViewController.frontViewController;
//Pass the Favorites Array -- The below code gives me an error that the property I set on the CheersViewController is not found.
rankingViewController.favoriteCheers = CheersViewController.myFavoriteCheersArray;
}
}
CONCEPT QUESTIONS I'D LOVE COMMENTARY ON:
What is the best (by best, I mean a balanced approach between implementation reality and academic purity) approach to make the array available to another view controller when a segue is not defined without butchering OO concepts/designs?
The rear view controller (the Sidebar) does not get loaded on app startup - instead it gets loaded on first display. Is it correct that I am therefore loading the data for the first time in the Cheers View Controller (i.e. I could make the Sidebar load on app startup but this seems conceptually wrong as well since the user may never access the Sidebar)?
Is it best to prep the my favorites array when the app first launches in the Cheers View Controller or only when My Favorites is first viewed? The list is rather small but technically if the user never clicked on the sidebar to view their favorites then I would be loading an extra array unnecessarily - probably a nit since the array is small but I am curious.
Is the proper place to load the data where I have it currently?
It seems to me that a delegate conceptually wouldn't make sense since the Cheers View Controller doesn't really need to be aware of a user viewing his/her favorites. All I'm really doing is trying to query a set of master data. Am I correct in thinking this way?