在 UISplitViewController 中重用详细视图控制器
Posted
技术标签:
【中文标题】在 UISplitViewController 中重用详细视图控制器【英文标题】:Reusing detailed view controller in UISplitViewController 【发布时间】:2011-05-11 10:50:45 【问题描述】:基本上,当我实现像 Apple 示例“MultipleDetailsViews”中所示的拆分视图时,一切正常,每次选择一行时它都会分配一个新的详细视图。以下是示例中的相关代码:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0)
FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];
detailViewController = newDetailViewController;
// ...
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
// ...
但我正在寻找的是重用详细的视图控制器,即在选择视图控制器时懒惰地分配它,并在我的对象中保留对它的引用。 That way when another row is selected the view controller is not deallocated and when it is selected again it would be reused instead of allocating a new one.以下是相关代码:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (row == 0)
if (self.firstDetailViewController == nil)
FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];
self.firstDetailViewController = newDetailViewController;
[newDetailViewController release];
detailViewController = self.firstDetailViewController;
// ...
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
// ...
self.firstDetailViewController
在第一次选择第一行时实例化,然后重复使用。
当我这样做时,它在横向模式下运行良好,但在弹出菜单中单击几下后在纵向模式下会引发异常:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Popovers cannot be presented from a view which does not have a window.'
那我为什么在乎呢?为什么我不想重新分配视图控制器?因为在其中一些任务中,如果用户在新的详细视图中导航而任务尚未完成,我希望执行不会被中断(杀死)的任务。
有没有人知道会发生什么或者我正在努力实现的目标的有效实施?
【问题讨论】:
如果表开始加载的行不是 0 怎么办?在这种情况下,detailViewController 将为 nil。 查看类似post的答案 【参考方案1】:视图控制器旨在创建和丢弃,如果您需要在后台运行更长的时间,那么最好将其移动到主视图控制器或单独的对象中。
如果您确实想尝试重用视图控制器,这可以通过在新导航控制器上设置 viewControllers 属性来实现,之前的细节控制器保存在 viewDidLoad 中:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDetail"])
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
UINavigationController* navigationController = (UINavigationController*)[segue destinationViewController];
// reuse existing controller
navigationController.viewControllers = @[self.detailViewController];
// update the detail controller as normal.
[controller setDetailItem:object];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
【讨论】:
以上是关于在 UISplitViewController 中重用详细视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
UISplitViewController:在 detailView 中导航
在 UISplitViewController 中使用 SwiftUI 列表侧边栏
UISplitViewController:为啥我不应该在导航或标签栏界面中显示它?