iPad SplitViewController递归向下钻取 - 访问DetailViewController

时间:2011-11-01 07:39:07

标签: ios ipad uisplitviewcontroller

我已经采用了基于标准iPad SplitViewerController模板的项目,并实现了递归深入导航到任意数量的级别,如下所示:

首先,我创建了一个新的视图控制器(名为NavItemController),我在RootViewController的didSelectRowAtIndexPath方法中弹出控制器堆栈,如下所示:

NavItemController  *navItemController = [[NavItemController alloc] initWithNibName:@"NavItemController" bundle:[NSBundle mainBundle]];
navItemController.title = catalogue.name;
[[self navigationController] pushViewController:navItemController animated:YES];

然后我使用此视图控制器在我的树结构中上下导航(因此RootViewController现在仅用于显示导航的初始根级别,即没有父级的项目。)

一切都很好。

现在,当我在NavItemController中选择一个项目时,我正在尝试更新详细视图(detailViewDescriptionLabel)上的标签。为此,我首先在我的NavItemController中添加了一个插座:

@property (nonatomic, strong) IBOutlet DetailViewController *detailViewController;

并在InterfaceBuilder中配置它,方法是将库中的视图控制器添加到Objects列表中,将其类更改为DetailViewController并挂钩我在文件所有者下找到的插座。

此时,如果我单步执行代码,我发现它正确地将详细视图中的detailItem设置为我在NavController中选择的对象 - 它似乎正确地将detailDescriptionLabel.text值设置为此detailItem中的值。然而,这并没有反映在UI中(如果我从RootViewController执行此操作,它仍然可以工作)。

我猜我没有正确地连接某些东西或错过了某个地方 - 我(显然)对iOS很新 - 任何指针都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我最后通过使用iOS 5和Master Detail模板从头创建项目来解决我的问题。我还选择使用故事板功能。

我能够使用MasterViewController(与早期模板中的RootViewController相同)进行递归导航,即我不需要创建单独的视图控制器。

MasterViewController中的代码didSelectRowAtIndexPath方法最终成为:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    self.detailViewController.detailItem = selectedObject; 

    NavItem *navItem = ((NavItem *) selectedObject);
    Catalogue *catalogue = nil;
    Document *document = nil;

    if (navItem.catalogue != nil) // Load child catalogues and documents
    {
        catalogue = [navItem catalogue];
        DataLoader *dataLoader =[(AppDelegate *)[[UIApplication sharedApplication] delegate] dataLoader];
        [dataLoader drillDownIntoNavItems:catalogue];
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];
        MasterViewController  *controller = [storyBoard instantiateViewControllerWithIdentifier:@"master"];
        controller.managedObjectContext = self.managedObjectContext;
        controller.title = catalogue.name;

        [[self navigationController] pushViewController:controller animated:YES];
    } 
    else if (navItem.document != nil) // Load attachments
    {
        document = [navItem document];
        DataLoader *dataLoader =[(AppDelegate *)[[UIApplication sharedApplication] delegate] dataLoader];
        [dataLoader drillDownIntoNavItems:document];
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];
        MasterViewController  *controller = [storyBoard instantiateViewControllerWithIdentifier:@"master"];
        controller.managedObjectContext = self.managedObjectContext;
        controller.title = document.name;
        [[self navigationController] pushViewController:controller animated:YES];

        // Display document in detail viewer
    }

    else // attachment
    {
        // Display attachment in popover
    }
}

同样重要的是MasterViewController中的viewWillDisappear方法:

- (void)viewWillDisappear:(BOOL)animated
{
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
        // back button was pressed. We know this is true because self is no longer
        // in the navigation stack. 
        DataLoader *dataLoader =[(AppDelegate *)[[UIApplication sharedApplication] delegate] dataLoader];
        [dataLoader drillUpIntoNavItems];
    }

    [super viewWillDisappear:animated];
}