0

私は常に楽しいレガシーコードをデバッグしています。古いコードでは、splitViewデリゲートメソッドをモックしようとしました。主にクラッシュしました.PlusデバイスではPortraitに、回転ではランドスケープでクラッシュしました。詳細ビューが設定されていない場合、古いコードが私は、splitviewのマスター側とディテール側の両方にナビゲーションスタックを持っています。私のアプリはUISplitViewControllerベースです。マスターとディテールの両方でnavスタックを持つUISplitViewController - どのスタックからVCを削除するのですか?

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テーブルビューメニュークラスクラス(AEContentMenuTableViewController)のテーブルビューに次の行を選択するために、次/前のボタンを有しています。私はAECourseHTML...が現在使用しているindexPathAEContentMenu...から呼び出せるデリゲート関数を呼び出し、それを呼び出すとメニューテーブルビュー行を選択し、新しい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; 
} 
関連する問題