0

我正在调试总是有趣的遗留代码。旧代码试图模拟代理方法,导致各种问题 - 主要是崩溃:在Portrait中的Plus设备上,旋转到横向导致崩溃 - 如果没有设置详细视图,则旧代码试图在狡猾的黑客和它只是没用...UISplitViewController带有导航堆栈在主和细节 - 如何从一个堆栈中删除一个VC?

我的应用程序是基于UISplitViewController,其中我在splitView的主和细节两侧都有一个导航堆栈。

通过读取虽然SO和使用this example,并能够实现UISplitViewController委托方法和一切工作正常关于旋转,并在适当时显示正确的主/细节视图。下面是我的实现:(道歉的代码片段墙)

- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController { 

    if ([secondaryViewController isKindOfClass:[UINavigationController class]] 
     && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[AECourseHTMLTableViewController class]] 
     && ([(AECourseHTMLTableViewController *)[(UINavigationController *)secondaryViewController topViewController] htmlContentEntry] == nil)) { 
     // If the detail controller doesn't have an item, display the primary view controller instead 
     return YES; 
    } 
    return NO; 
} 

而另SPLITVIEW委托方法 - 看到代码中的注释为我被困在那里。

- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController { 
    // If detail view already exists 
    if ([primaryViewController isKindOfClass:[UINavigationController class]]) { 
     for (UIViewController *controller in [(UINavigationController *)primaryViewController viewControllers]) { 
      if ([controller isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)controller visibleViewController] isKindOfClass:[AECourseHTMLTableViewController class]]) { 
       return controller; 
      } 
     } 
    } 

    // Create detail view 
    UINavigationController *navController = [self.storyboard instantiateViewControllerWithIdentifier:@"CourseHTMLNav"]; 
    if ([navController.viewControllers.firstObject isKindOfClass:[AECourseHTMLTableViewController class]]) { 
    AECourseHTMLTableViewController *courseViewController = navController.viewControllers.firstObject; 
    [self configureViewController:courseViewController entry:self.contentSection.sections[0] indexPath:courseViewController.currentIndexPath]; 
    } 

    // Enable back button 
    UIViewController *controller = [navController visibleViewController]; 
    controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 
    controller.navigationItem.leftItemsSupplementBackButton = YES; 

    if (!self.splitViewController.isCollapsed) { 
     UINavigationController *navController = self.splitViewController.viewControllers.firstObject; 
     AEContentMenuTableViewController *contentMenuVC = navController.viewControllers.firstObject; // This controller needs to be master in Landscape 

     NSMutableArray<UIViewController *> *controllers = [navController.viewControllers mutableCopy]; // Contains 3 controllers, first needs removed 
     NSMutableArray *toDelete = [NSMutableArray new]; 

    for (UIViewController *viewController in controllers) 
     if ([viewController isKindOfClass:[contentMenuVC class]] || [viewController isKindOfClass:[AECourseHTMLTableViewController class]]) { 
      [toDelete addObject:viewController]; // Remove first VC, so master should become AEContentMenuVC? 
      break; 
     } 

    // Remove the object 
    [controllers removeObjectsInArray:toDelete]; 

    // Set viewControllers 
    navController.viewControllers = controllers; 
    } 
    return navController; 
    } 

AECourseHTMLTableViewController具有下一/先前的按钮在菜单的tableview类类(AEContentMenuTableViewController)的tableview中选择下一行。我有一个代理功能,可以告诉我当前indexPath其中AECourseHTML...正在使用从AEContentMenu...,并调用它时,它选择菜单tableview行并实例化一个新的AECourseHTML...并将其推。

这是我卡住的地方。在肖像中,按next/prev很好,它会选择正确的行并按预期工作。但是,一旦我旋转设备,主视图和详细视图都会显示详细视图。我可以在主视图上按“返回”,它将我带到正确的AEContentMenu...类。如代码片段注释中所述,我需要从主堆栈(实际上是第一个对象)中移除一个ViewController,并且AEContentMenu...应该成为该堆栈的第一个对象 - 因此在旋转时应该是主视图。

对于这么长的帖子道歉,我已经用了几个星期的时间来敲打我的头,我想在这个问题中尽可能多地包含信息。提前致谢。

回答

0

我发现了一个适合我的用例的解决方案。它可能不是最干净的代码,但我很满意我得到的。

splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: 保持不变。我已经用解决方案更新了我的splitViewController:separateSecondaryViewControllerFromPrimaryViewController:委托方法。欢迎任何反馈。

- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController { 
    // If detail view already exists 
    if ([primaryViewController isKindOfClass:[UINavigationController class]]) { 
     for (UIViewController *controller in [(UINavigationController *)primaryViewController viewControllers]) { 
      if ([controller isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)controller visibleViewController] isKindOfClass:[AECourseHTMLTableViewController class]]) { 
       return controller; 
      } 
     } 
    } 

    // Return CourseVC 
    UINavigationController *navController = splitViewController.viewControllers.firstObject; 
    UIViewController *viewController; 
    for (viewController in navController.viewControllers) { 
     if ([navController.viewControllers.lastObject isKindOfClass:[AECourseHTMLTableViewController class]]) { 
      return viewController; 
     } else { 
      // Create detail view 
      UINavigationController *navController = [self.storyboard instantiateViewControllerWithIdentifier:@"CourseHTMLNav"]; 
      if ([navController.viewControllers.firstObject isKindOfClass:[AECourseHTMLTableViewController class]]) { 

       // Enable back button 
       UIViewController *controller = [navController visibleViewController]; 
       controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; 
       controller.navigationItem.leftItemsSupplementBackButton = YES; 

       AECourseHTMLTableViewController *courseViewController = navController.viewControllers.firstObject; 
       // If next/prev has been tapped, configure current ContentHTML 
       if (self.currentContentHTML) { 
        [self configureViewController:courseViewController entry:self.currentContentHTML indexPath:courseViewController.currentIndexPath]; 
       } else { 
        // Create new ContentHTML from first row of AEContentMenuVC 
        [self configureViewController:courseViewController entry:self.contentSection.sections[0] indexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
       } 
       return navController; 
      } 
     } 
    } 
    return navController; 
}