2014-01-30 37 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

相關問題