2014-01-30 34 views
2

快速背景:如何使用SWRevealViewController在两个视图之间传递数组?

我有一个应用程序,显示在搜索的歌曲列表,标签式界面(又名“干杯视图控制器”)。有两个选项卡,每个类型的我的欢呼。我有一个侧边栏,允许您选择菜单选项,其中之一称为“我的收藏夹”。它使用SWReveal控制器(又名“侧边栏”)。我试图让用户在游戏时间之前标记出最喜欢的欢呼声,然后使用侧边栏导航快速查看喜爱的歌曲列表。

我的应用程序的初始视图控制器是一个Reveal视图控制器。

前视图(sw_front)是标签栏控制器,该应用程序第一次启动时显示干杯视图控制器。将数据加载到Cheers View Controller的ViewDidLoad中的CSV文件中。

后部控制器(sw_rear)是侧边栏,它定义了我的应用程序的菜单选项。我的补充工具栏上的其中一个菜单选项叫做我的收藏夹。这是侧边栏,它在概念上抛出我。请参阅下面的快照,了解我的故事板的相关区域。

STORYBOARD快照: 事实证明,作为新用户,我无法发布图片。 :(

目标

我试图从访问喜爱的欢呼声阵列中的干杯 - 视图 - 控制器我的最爱视图控制器。目前没有干杯查看SEGUE控制器我的收藏它看起来像定义一个segue在这里是错误的概念

我不想使用单身或其他工作,我宁愿以正确的方式构建我的应用程序。一个简单的解决方案是将我的收藏夹移到标签栏控制器的另一个选项卡上。虽然我可以改变设计,事情可能会更容易,但我觉得我错过了一个有价值的概念,可以在以后的应用程序中使用。

我意识到有很多帖子已经在从一个控制器传递数据到另一个控制器的主题。我已经阅读了我认为的全部,但是我还没有能够成功地将这些解决方案整合到SWRevealController实现中。很显然,我对机制或概念(或两者)都感到困惑。我阅读的大多数帖子都涉及两个控制器之间的赛段或传球领域,他们之间有某种关系或某种关系。

力学问题:

我目前预习在主选项卡式接口表视图控制器的viewDidLoad中最爱阵列。加载主数组后,立即执行此操作,并从CSV文件中读取所有歌曲。我在想,我可以以某种方式通过这个我的收藏表视图控制器或访问它从我的收藏表视图控制器。

//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]; 

这里就是它得到粘我 - 当用户点击该按钮,显示侧栏,然后点击我的最爱

边栏将与执行的prepareForSegue这个:

- (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]; 
     }; 

    } 

我试图将这添加到prepareForSegue的结尾,以某种方式允许我的收藏夹的访问到数组...但我无法从侧边栏识别欢呼视图控制器属性...

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; 
    } 


} 

概念的问题我很想述评:

  1. 什么是最好的(最好的,我的意思是实现现实和学术纯度之间的平衡方法)的方法使数组可用于另一个视图控制器时,如果没有屠宰面向对象的概念/设计没有定义一个segue?

  2. 后视图控制器(侧栏)在应用程序启动时未加载 - 取而代之的是在第一次显示时加载。这是否正确,因此我第一次在Cheers View Controller中加载数据(即,我可以在应用程序启动时创建边栏加载,但这在概念上似乎也是错误的,因为用户可能永远不会访问边栏)?

  3. 它是最好的来准备我的最爱阵列当干杯视图控制器应用程序第一次启动或仅我的最爱时首先看?该列表相当小,但从技术上讲,如果用户从未点击侧边栏查看他们的收藏夹,那么我将不必要地加载额外的数组 - 可能是一个尼特,因为数组很小,但我很好奇。

  4. 加载数据的位置是否正确?

  5. 在我看来,代理概念上没有意义,因为Cheers View Controller并不需要知道用户正在查看他/她的最爱。我所做的只是试图查询一组主数据。我以这种方式思考是否正确?

+0

我正在寻找的许多答案可以在这里找到:http://stackoverflow.com/questions/569940/whats-the-best-way-to-communicate-between-view-controllers – Keeve

回答

0

这是如何解决这些问题。他们的工作 - 至于他们是否最好,我会让你知道,因为我了解更多。 grinder

问题1:从AppDelegate didFinishLaunchingWithOptions中的plist,CSV或任何其他源文件加载一组初始数据。例如:

//Read in from JSON file 
NSError *error; 
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Cheers" ofType:@"json"]]; 
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 

self.cheersArray = json[@"cheers"]; 

该数组可以是不可变的(即,NSArray),你可以将其转换为视图控制器,如果需要的话,可以将其作为NSMutableArray进行操作。例如:

//Instantiate initial view controller 
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 
CMViewController *cmViewController = [storyboard instantiateInitialViewController]; 

//Pass array of data into a table view controller 
cmViewController.tableData = (NSArray *)self.tableData; 

这假定您的View Controller具有可用于传递数据的属性。

如果你有一个JSON文件,并需要它是一个PLIST,还有通过终端的伟大事业上你的Mac

plutil -convert xml1 InputFileName.json -o OutputFileName.plist 

当你学会像我一样,你可以实现的Plist与行的数量较少比JSON文件更受欢迎,并且在保存数据更改(如果您的应用程序允许的话)的时候更容易处理(个人意见)。

问题2:从学术角度来看,在应用程序启动时加载侧边栏在概念上是错误的。它只能在第一次使用时加载。

问题3:与问题2类似,最好将首选项数组传递给第一次请求时需要它的视图控制器(即用户按下“收藏夹”选项卡。由于技术上收藏夹只是一个特定的视图我加载的主数据的一个子集,我相信这是正确的。

问题4:我将它从第一个视图控制器移到App Delegate,如上所示,这给我更多的灵活性来传递数据(从概念上讲,从父母到孩子的视图控制器)而不是跨越(从孩子到孩子的视图控制器)。这简化了我的代码。

问题5:我不相信委托是适当的te为我面临的挑战的答案。

随时评论!

+0

请注意,你也可以如果你喜欢,也可以在初始视图控制器中加载数据。这个视图控制器可以是应用程序的父视图控制器。我只是不确定哪个地方是“最佳做法”,或者它是更多情景/个人偏好。 – Keeve

相关问题