Ipad 需要UISplitViewController为详图视图控制器延迟加载多个视图控制器

Ipad 需要UISplitViewController为详图视图控制器延迟加载多个视图控制器,ipad,lazy-loading,uitableview,uisplitviewcontroller,uipopovercontroller,Ipad,Lazy Loading,Uitableview,Uisplitviewcontroller,Uipopovercontroller,嗯,标题可能不清楚。我从苹果公司的示例代码中提取了这一点。每次用户从弹出窗口中的表中选择一行时,detailViewController都会再次分配给FirstDetailViewController和SecondDetailViewController。我不想一遍又一遍地分配和初始化视图控制器,而是想在选择行时将现有的、已经分配和初始化的视图控制器(如果存在)分配给detailViewController。我修改了分割视图模板,而不是示例代码,以实现我需要的功能。程序中的代码: 这是AppDe

嗯,标题可能不清楚。我从苹果公司的示例代码中提取了这一点。每次用户从弹出窗口中的表中选择一行时,detailViewController都会再次分配给FirstDetailViewController和SecondDetailViewController。我不想一遍又一遍地分配和初始化视图控制器,而是想在选择行时将现有的、已经分配和初始化的视图控制器(如果存在)分配给detailViewController。我修改了分割视图模板,而不是示例代码,以实现我需要的功能。程序中的代码:

这是AppDelegate.h文件:

@interface iPadHelloWorldAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;

    UISplitViewController *splitViewController;

    MasterViewController *masterViewController;
    DetailViewController *detailViewController;
    SecondDetailViewController *secondDetailViewController;
}
这是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];
}
#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;
}
这是DetailViewController。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];
}
#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;
}
我可以懒洋洋地加载视图控制器,但当我点击弹出窗口的条形按钮并跳转到第二个视图控制器时,第二个视图控制器不会显示弹出窗口。当我跳回第一个局部视图控制器时,会显示弹出框


基本上,这是一个类似的问题。但是指向下拉框的链接不起作用。

尝试在该对象的ViewDiLoad中分配ViewController。为两个ViewController指定一个标题,并将它们放入一个数组中。如果需要,这些标题可用于两个单元格文本标签。 在didSelectRowAtIndexPath中,可以为所选行获取正确的viewcontroller

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

既然你要我开枪,就这样吧。从我们这里的观点来看,SplitViewController相当有缺陷。如果您不严格按照Apple在其示例代码中的方式操作,我们会遇到很多问题

首先,我建议您再次使用示例代码,从头开始,因为您似乎修改了很多

至于您的问题:在您的委托和MainWindow.xib中,您设置了SplitViewController。最重要的是不要按您的方式设置ViewController阵列

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

请尝试只设置一次RootViewController(TableViewController),不要在ViewController属性中覆盖它。不过,对于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];     

    } 
}

无需创建局部视图控制器的新实例或更新拆分视图控制器中的视图控制器

试试这个

    - (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:请将标签拖到细节处进行测试。

这是一个解决方案(延迟加载)。但每次选择一行时,都会执行if语句。不够充分。查看我的编辑以获得我将选择的解决方案。嘿,我尝试了这个。。。我收到了这个错误-无法从没有窗口的视图中显示弹出窗口。这段代码在您的UISPlitViewController中吗?错误(代码)在哪里?我想如果您可以查看示例程序MultipledTailViews的代码,会更容易一些。它位于RootViewController.m中。我使用与示例中完全相同的代码,并按照您的建议进行了更改。它在UISplitVIewController中。嘿,Mats,我仍然不知道如何解决这个问题。我已经用我在程序中修改过的一些东西更新了这个问题。@Icky:嘿,谢谢你的回答,是的,splitviewcontroller真的有问题。我照你说的做了。我在我的委托和MainWindow.xib中设置了splitView。但是如何设置视图控制器阵列?无论如何,谢谢你的帮助。@Icky:顺便说一句,我只想再次简化我的问题。当在根视图控制器中选择一行时,我想加载一个新的视图控制器,当再次选择同一行时,我不应该再次为视图控制器分配,因为它已经分配了一次。苹果的示例代码不允许这样做。可以分配一个新的视图控制器,这取决于您需要什么。检查我上面的代码-它对我有效…@Icky:对不起,我可能不清楚。我不想再分配了。基本上是惰性加载视图控制器(如果以前已经分配过)。您没有设置popovercontroller。新的视图控制器应具有popoverController属性,更换后需要将其设置为当前popoverController。类似于:dvC.popoverController=[[appDelegateiPad.splitViewController-viewControllers]objectAtIndex:1]popoverController];