【问题标题】:why does this code use presentModalViewController? (not pushViewController)为什么这段代码使用 presentModalViewController? (不是 pushViewController)
【发布时间】:2011-07-03 01:03:12
【问题描述】:

任何人都明白为什么在 CoreDataBooks 示例代码中:

(a) 控制器交换差异的方法

虽然单击项目并转到详细视图使用似乎是“pushViewController”的标准 UINavigationController 概念,但当您单击“添加”新记录按钮时,它会启动通过“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];

}

谢谢

【问题讨论】:

    标签: iphone ios uiviewcontroller uinavigationcontroller modalviewcontroller


    【解决方案1】:

    您使用模态视图控制器将用户的注意力集中在任务上。当您推送时,用户处于某种导航流程中,但仍然触手可及整个应用程序。他们可能会决定前进或后退,切换到中间的不同选项卡,无论如何。当他们获得模态视图控制器时,他们无法执行任何操作,直到任务完成或取消(模态视图被解除)

    【讨论】:

      【解决方案2】:

      [警告:此答案更多地适用于 CoreDataBooks 的更新代码,该代码已更改为使用 NSManagedObjectContext 的 iOS5 中的新 setParentContext 方法,而不是与 persistentStoreCoordinator 混淆[

      模态添加与非模态编辑方法也回答了您关于数据共享的第二个问题。在模拟器中运行应用程序并注意:

      1. 如果您单击“添加”,您的下一个视图将同时具有“保存”和“取消”按钮

      2. 如果您点击编辑,您的下一个视图只有一个“完成”按钮。

      (现在,在这个特定项目中,您必须一次编辑每个字段,并且字段编辑在另一个视图中完成,并且该视图有一个取消按钮,但现在忽略它,因为

      一个。这仅适用于该领域。例如。如果您编辑标题并点击保存,您将返回带有完成按钮的编辑视图,现在无法取消撤消该更改,您只能点击完成。就这个视图而言,您已经编辑了 Book 模式

      b.多么蹩脚的用户界面!来吧,Apple,将 CoreDataBooks 变成一个体面的,虽然简单的应用程序,遵循你自己的约定。至少把编辑放在单元格中。)

      我们在哪里?哦,是的,现有 Book 的“编辑”是无模式的,因此它会在同一个 MOC (NSManagedObjectContext) 中传递原始 Book,并且您无法在 Edit 视图中取消对它的编辑。 另一方面,“添加”一本书是 MODAL:它创建一个新书以在详细视图中进行编辑,并希望在用户点击取消时丢弃它。为了实现这一点,它必须使用第二个 MOC,它是第一个的子 MOC。如果用户取消,它会简单地忽略新的子 MOC,有效地丢弃新书;如果用户保存,它保存子 MOC,它将新书及其属性向上推送到父 MOC,然后保存父 MOC。

      顺便说一句,这种子 MOC 方法在 WWDC 2011 演示文稿 303“iOS 上的 Core Data 中的新功能”中有详细说明。 SO 中的其他地方还讨论了其他方法,包括

      • 使用 nil MOC 创建一个新的托管对象,并且仅在用户点击保存时将其插入到父 MOC 中

      • 不使用托管对象,而是为临时对象(我们不确定是否要保存的新书)使用不同的数据结构,例如 NSDictionary,或者只是一组不同的变量

      • 还有更多... ?

      我更喜欢父子方法,因为 Apple 喜欢它,并且因为它利用数据模型对象而不是为临时对象创建并行数据结构。 nil-context 方法也有这个好处,以及(显然)更好的性能和简单性的额外好处(读我的嘴唇:没有新的 MOC)。但我不相信没有托管对象上下文的托管对象是洁净的。

      顺便说一句,CoreDataBooks 并没有完全遵循上述演示中规定的约定,因为它没有将 parent 上下文保存在 performBlock 块中。

      我也不确定为什么它将新的托管上下文设置为 AddViewController 上的属性并且不使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        • 2010-09-18
        相关资源
        最近更新 更多