要求UISplitViewController延迟加载详细视图控制器的多个视图控制器

时间:2011-02-16 09:07:59

标签: ipad lazy-loading uitableview uisplitviewcontroller uipopovercontroller

嗯,可能不清楚标题。我从Apple的MultipleDetailView示例代码中取出了这个权利。每次用户从弹出窗口中的表中选择一行时,detailViewController将再次分配FirstDetailViewController和SecondDetailViewController。而不是一遍又一遍地分配和初始化视图控制器,我想分配现有的和已经分配和初始化的视图控制器,如果在行的选择上存在于detailViewController中。我修改了拆分视图模板而不是示例代码来实现我的需要。该计划的代码:

这是AppDelegate.h文件:

@interface iPadHelloWorldAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

    UISplitViewController *splitViewController;

    MasterViewController *masterViewController;
    DetailViewController *detailViewController;
    SecondDetailViewController *secondDetailViewController;
}

这是AppDelegate.m文件:

 masterViewController = [[MasterViewController alloc] init];
 UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
 detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:nil];
 secondDetailViewController = [[SecondDetailViewController alloc] initWithNibName:@"SecondDetailView" bundle:nil];
 splitViewController = [[UISplitViewController alloc] init];
 splitViewController.viewControllers = [NSArray arrayWithObjects:navigationController, detailViewController, nil];
    splitViewController.delegate = detailViewController;
    // Add the split view controller's view to the window and display.
    [window addSubview:splitViewController.view];
    [window makeKeyAndVisible];

这是MasterViewController.m:

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = indexPath.row;
    [self.appDelegate.splitViewController viewWillDisappear:YES];
    self.tempArrays = [NSMutableArray arrayWithArray:self.appDelegate.splitViewController.viewControllers];
    [self.tempArrays removeLastObject];
    if (row == 0) {
        [self.tempArrays addObject:self.appDelegate.detailViewController];
        self.appDelegate.splitViewController.delegate = self.appDelegate.detailViewController;
    }
    if (row == 1) {
        [self.tempArrays addObject:self.appDelegate.secondDetailViewController];
        self.appDelegate.splitViewController.delegate = self.appDelegate.secondDetailViewController;
    }
    self.appDelegate.splitViewController.viewControllers = self.tempArrays;
    [self.appDelegate.splitViewController viewWillAppear:YES];
}

这是DetailViewController.m:

#pragma mark -
#pragma mark Split view support

- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc {

    barButtonItem.title = @"Master List";
    [navigationBar.topItem setLeftBarButtonItem:barButtonItem animated:NO];
    self.popoverController = pc;
}

// Called when the view is shown again in the split view, invalidating the button and popover controller.
- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {

    [navigationBar.topItem setLeftBarButtonItem:nil animated:NO];
    self.popoverController = nil;
}

我可以延迟加载视图控制器,但是当我点击弹出窗口的栏按钮并跳转到第二个视图控制器时,第二个视图控制器不会显示弹出窗口。当我跳回第一个细节视图控制器时,会显示弹出窗口。

基本上,here是一个类似的问题。但是那里的投递箱的链接不起作用。

3 个答案:

答案 0 :(得分:3)

因为你要我开枪 - 这就是它。从我们这里的意见来看,SplitViewController相当错误。如果你不像他们的示例代码那样坚持Apple的方式,我们遇到了很多问题。

首先,我建议你再次采用示例代码并从头开始,因为它似乎已经修改了很多。

至于你的问题:在你的委托和MainWindow.xib中你设置了SplitViewController。最重要的是不要像你那样设置viewControllers数组。

我遇到的问题是,如果我覆盖RootViewController,它会搞乱SplitViewController并产生类似你遇到的错误。

尝试只设置一次RootViewController(TableViewController),并且永远不会在viewControllers属性中覆盖它。但是,对于DetailViewController,这似乎没问题。

其次,您的代码应该放在其他地方,而不是放在RootViewController中。这应该仅适用于tableView数据源和内容。

试试这个并在此反馈,我会尽快跟进。

祝你好运。

编辑:代码添加 - 在RootViewController中执行此操作:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here. Create and push another view controller.

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {


DetailViewController *dvC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];

// take the original view controller from the splitviewcontroller as root
// appDelegateiPad defined like this in my appdelegate:
// #define appDelegateiPad ((AppDelegate_iPad *)[[UIApplication sharedApplication] delegate]) 
NSArray *viewControllers = [[NSArray alloc] initWithObjects:[[appDelegateiPad.splitViewController viewControllers]objectAtIndex:0], dvC, nil];
        appDelegateiPad.splitViewController.viewControllers = viewControllers;
//careful with this, set it to whatever your delegate is in your case           
appDelegateiPad.splitViewController.delegate = dvC;
        [viewControllers release];  


//this is my version
//i have the popoverController property in my detailviewcontroller. this is where my splitviewcontroller delegate methods are. you need to set the popovercontroller property in the class where your splitviewcontroller delegate methos are
    dvC.popoverController = [[[appDelegateiPad.splitViewController viewControllers]objectAtIndex:1] popoverController];     

    } 
}

答案 1 :(得分:0)

尝试在此对象的viewDidLoad中分配viewControllers。为两个viewcontrollers提供一个标题并将它们放在一个数组中。如果需要,您可以将这些标题用于两个单元格文本标签。 在didSelectRowAtIndexPath中,您可以获得所选行的正确viewcontroller

UIViewController <SubstitutableDetailViewController> *detailViewController = [theArray objectAtIndex:indexPath.row];

编辑:

@interface SomeClass : NSObject {
  NSArray *controllerArray;
}
@end
@implementation SomeClass

- (void) viewDidLoad {
  controllerArray = [[NSArray alloc] initWithObject://yourControllers//,nil];
  [super viewDidLoad]
}

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {

    // Two sections, one for each detail view controller.
    return 2;
}

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  //Create Cell

  UIViewCOntroller *controller = [controllerArray objectAtIndex:indexPath.row];
  cell.textLabel.text = controller.title;

  return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  [detailViewController autorelease]; 
  detailViewController = [[controllerArray objectAtIndex:indexPath.row] retain];
}

@end

答案 2 :(得分:0)

无需在拆分视图控制器中创建详细视图控制器的新实例或更新viewControllers。

试试这个。

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {

        UIApplication *application = [UIApplication sharedApplication];
        AppDelegate *appDelegate = (AppDelegate*) [application delegate];
        appDelegate.detailViewController.label.text = @"Detail view controller updated";

    }

PS:请将标签拖到细节上进行测试。

相关问题