4

任何人都明白,爲什麼在CoreDataBooks示例代碼:爲什麼此代碼使用presentModalViewController? (不pushViewController)

(一)控制器的方法交換差異

雖然按項目並進入詳細視圖使用什麼似乎是標準的UINavigationController概念「pushViewController」,即當你點擊「添加」一個新的記錄按鈕時,它啓動新的視圖,通過「presentModalViewController」方法添加記錄?也就是說,兩種情況下的方法都不一樣,只是使用pushViewController方法?

使用每種方法實際上有什麼優勢嗎?我看不到。我猜想蘋果公司一定會爲不同的場景選擇不同的方法。例如:

  1. 給用戶的任何差異(即 UI差異或功能 差異),他們會看到什麼?

  2. 對於開發商 (或優勢/劣勢)的任何差異

例如,如果你要考慮使用pushViewController方法,而不是針對的presentModalViewController方法爲「添加」的情況.. 。

(b)中的數據共享的方法差異

他們如何分享共同數據對象的方法似乎有所不同 - 所以又想知道爲什麼這些方法不一樣? (即,在兩種情況下,主控制器被傳遞到另一個視圖暫時和在它們之間存在一些共享的數據 - 即該子視圖需要傳遞迴父)

代碼提取用於便利

這是 「編輯」:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // Create and push a detail view controller. 
    DetailViewController *detailViewController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; 
    Book *selectedBook = (Book *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; 

    // Pass the selected book to the new view controller. 
    detailViewController.book = selectedBook; 
    [self.navigationController pushViewController:detailViewController animated:YES]; 
    [detailViewController release]; 
} 

但對於 「添加」

- (IBAction)addBook { 
    AddViewController *addViewController = [[AddViewController alloc] initWithStyle:UITableViewStyleGrouped]; 
    addViewController.delegate = self; 

    // Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context. 
    NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init]; 
    self.addingManagedObjectContext = addingContext; 
    [addingContext release]; 

    [addingManagedObjectContext setPersistentStoreCoordinator:[[fetchedResultsController managedObjectContext] persistentStoreCoordinator]]; 
    addViewController.book = (Book *)[NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:addingContext]; 
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController]; 
     [self.navigationController presentModalViewController:navController animated:YES]; 

    [addViewController release]; 
    [navController release]; 

} 

謝謝

回答

9

您可以使用模態視圖控制器將用戶的注意力集中在任務上。當你推動時,用戶處於某種導航流程中,但總體應用程序仍處於觸手可及的狀態。他們可能會決定前進還是後退,切換到中間的其他選項卡,無論如何。當他們得到一個模態視圖控制器,他們不能做任何事情,直到任務完成或取消(模態視圖被駁回)

1

[警告:此答案適用於更多的代碼的CoreDataBooks ,它已更改爲使用NSManagedObjectContext中的new-in-iOS5 setParentContext方法,而不是與persistentStoreCoordinator混淆[

有關數據共享的第2個問題也可以通過模態添加vs無模式編輯方法來解決。在模擬器中運行的應用程序,請注意:

  1. 如果你點擊添加您的下一個視圖既具有保存和取消按鈕

  2. 如果你點擊編輯你的下一個視圖具有只有一個完成按鈕。

(現在,在這個特定的項目,你必須在一個時間內編輯每個字段和現場編輯在另一個視圖完成的,並且一個一個取消按鈕,但忽略了現在,因爲

a。這僅適用於該字段,例如,如果您編輯標題並點擊保存,您將返回到編輯視圖並顯示完成按鈕,現在沒有取消撤銷該更改,只能點擊完成。就這個觀點而言,你已經編輯了書籍模式,但是你已經編輯了書籍模式:

b。多麼糟糕的用戶界面!來吧蘋果,使CoreDataBooks成爲一個體面的,儘管簡單的應用程序你自己的約定。至少把編輯放在單元中。)

我們在哪裏?哦,是的,「編輯」 - 現有書籍是modeLESS,所以它在同一個MOC(NSManagedObjectContext)中傳遞原始書籍,並且無法在編輯視圖中取消對它的編輯。 「添加」 -ing一書,而另一方面是模態:它創造了在詳細視圖要編輯一本新書,並希望丟棄,如果用戶點擊取消。爲了達到這個目標,它必須使用第二個MOC,這是第一個孩子。如果用戶取消,它只是忽略新的小孩MOC,有效地丟棄新的書;如果用戶保存,則節省孩子MOC,其將新書及其屬性上推到父母MOC中,然後保存父母MOC。

這孩子,MOC方法,順便說一句,在WWDC 2011演示文稿303「是什麼在iOS上的核心數據的新的」詳細說明。 有在SO別處討論的其它方法,包括

  • 創建一個新的管理對象具有零MOC,並且當用戶點擊保存

  • 不使用管理只在父MOC插入它對象,但臨時對象(我們不確定我們想要保存的新書)的不同數據結構,例如NSDictionary,或者只是一組不同的變量

  • 以及更多...?

我有點喜歡親子方法,因爲蘋果有利於它,因爲它使用的數據模型的對象,而不是臨時對象的創建並行數據結構。 無環境方法也具有這樣的好處,以及(顯然)更好的性能和簡單性(閱讀我的嘴脣:沒有新的MOC)的額外好處。但我不相信沒有託管對象上下文的託管對象是猶太教。

順便說一下,CoreDataBooks並不完全遵循上述演示文稿中規定的約定,因爲它不會將父級上下文保存在performBlock塊中。

另外我不確定爲什麼它將新的託管上下文設置爲AddViewController上的屬性,並且不使用它。

相關問題