gpt4 book ai didi

uinavigationcontroller - 在 iOS 8 中 UISplitViewController 的主视图中有一个 UINavigationController

转载 作者:行者123 更新时间:2023-12-04 00:13:36 31 4
gpt4 key购买 nike

在我的 UISplitViewController ,主 View 是UINavigationController包含 UITableViewController .有时,当用户选择表中的项目时,我不得不再推一次 UITableViewController在主 View 中的现有表上。

在 iOS 7 中,我的第一个 UITableViewController我只是打电话

[self.navigationController pushViewController:otherTableVC animated:YES];

在 iOS 8 中:

当拆分 View 折叠时,otherTableVC 变成了详细 View !
然后旋转设备后,我们看到并排的两张 table ......

更糟糕的是,如果设备显示两个 Pane ,则代码运行良好,第二个表会被推到主 View 中的第一个表之上。但是,经过双重旋转后,两张 table 又并排了。似乎是 UISplitViewController的折叠模式干扰了我自己的导航 Controller ......

我如何管理自己的 UINavigationController在主 View 中?

谢谢

编辑:

我的主 View 和详细信息 View 都有一个导航 Controller 。为了解决我的问题,我刚刚发现,在折叠模式下,我必须创建一个额外的导航 Controller 并将其推送到主导航 Controller 上。
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:otherTableVC];
[self.navigationController pushViewController:navController animated:YES];

所以我刚刚发现我们可以将导航 Controller 插入另一个导航 Controller 中。

最佳答案

简短的回答,您可以通过 UISplitViewControllerDelegate 方法控制此行为:

splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
splitViewController:separateSecondaryViewControllerFromPrimaryViewController:

我怀疑你真正想要做的是处理你有一个基于 iOS 8 UISplitViewController 的应用程序的情况,你的主要和详细 View 都是 UINavigationControllers 并且有一些 viewControllers(在这些导航 Controller 中)你只想出现在拆分 View 的主要或细节侧。下面的答案处理这个。它还可以处理您有时希望 View 替换 Detail 导航 Controller 中的 View 而不是被推送到那里的情况。

一个小小的警告:下面的代码没有处理所有可能的情况,并且有一些假设:
  • 当拆分 View 折叠并且这些 View 被其上方的详细 View 遮挡时,我们不希望详细导航 Controller 堆栈上的任何内容发生变化。
  • 我们的 UIViewController 子类都有一个 shouldDisplayInDetailedView 和 shouldReplaceDetailedView 属性
  • 我们假设我们只将 View 推送到设置了 shouldDisplayInDetailedView 属性的详细导航 Controller 上。
  • View Controller 通过 splitViewController:showDetailViewController: 或 pushViewController:animated: 添加到详细 View 中 View 的 navigationController 属性(处于展开或折叠状态)。
  • 应该替换细节导航 Controller 中的 View Controller 的 View Controller 只能通过 splitViewController:showDetailViewController: 添加,并且只能通过与主 View Controller 中的 View 交互,即,只有当主 View Controller 在折叠时没有被遮挡时才会发生状态。
  • 当拆分 View Controller 展开时,我们有一个 BlankViewController 显示在细节 View 中,但我们只有应该留在主端的 View Controller 。

  • 我不建议只实现 splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:/splitViewController:separateSecondaryViewControllerFromPrimaryViewController: 逻辑的一侧并取决于另一侧的默认实现。 Apple 做了一些奇怪的事情,例如将 Detail 侧的 UINavigationViewController 作为主导航 Controller 堆栈中的 viewController 之一放入主侧,然后将其他 View Controller 插入其上方,即使您完全理解仍然无法从中复制你自己的代码。因此最好自己处理过程的双方。

    这是我使用的:

    #pragma mark -
    #pragma mark Split View Controller delegate.

    - (BOOL)splitViewController:(UISplitViewController *)splitViewController showViewController:(UIViewController *)vc sender:(id)sender
    {
    //Standard behaviour. This won't get called in our case when the split view is collapsed and the primary view controllers are obscured.
    return NO;
    }

    // Since we treat warnings as errors, silence warning about unknown selector below on UIViewController subclasses.
    #pragma GCC diagnostic ignored "-Wundeclared-selector"


    - (BOOL)splitViewController:(UISplitViewController *)splitViewController showDetailViewController:(UIViewController *)vc sender:(id)sender
    {
    if (splitViewController.collapsed == NO)
    {
    // The navigation controller we'll be adding the view controller vc to.
    UINavigationController *navController = splitViewController.viewControllers[1];

    UIViewController *topDetailViewController = [navController.viewControllers lastObject];
    if ([topDetailViewController isKindOfClass:[BlankViewController class]] ||
    ([vc respondsToSelector:@selector(shouldReplaceDetailedView)] && [vc performSelector:@selector(shouldReplaceDetailedView)]))
    {
    // Replace the (expanded) detail view with this new view controller.
    [navController setViewControllers:@[vc] animated:NO];
    }
    else
    {
    // Otherwise, just push.
    [navController pushViewController:vc animated:YES];
    }
    }
    else
    {
    // Collapsed. Just push onto the conbined primary and detailed navigation controller.
    UINavigationController *navController = splitViewController.viewControllers[0];
    [navController pushViewController:vc animated:YES];
    }

    // We've handled this ourselves.
    return YES;
    }

    - (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController
    {
    UINavigationController *primaryNavController = (UINavigationController *)primaryViewController;
    UINavigationController *secondaryNavController = (UINavigationController *)secondaryViewController;
    UIViewController *bottomSecondaryView = [secondaryNavController.viewControllers firstObject];
    if ([bottomSecondaryView isKindOfClass:[BlankViewController class]])
    {
    NSAssert([secondaryNavController.viewControllers count] == 1, @"BlankViewController is not only detail view controller");
    // If our secondary controller is blank, do the collapse ourself by doing nothing.
    return YES;
    }

    // We need to shift these view controllers ourselves.
    // This should be the primary views and then the detailed views on top.
    // Otherwise the UISplitViewController does wacky things like embedding a UINavigationController inside another UINavigation Controller, which causes problems for us later.
    NSMutableArray *newPrimaryViewControllers = [NSMutableArray arrayWithArray:primaryNavController.viewControllers];
    [newPrimaryViewControllers addObjectsFromArray:secondaryNavController.viewControllers];
    primaryNavController.viewControllers = newPrimaryViewControllers;

    return YES;
    }

    - (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController
    {
    UINavigationController *primaryNavController = (UINavigationController *)primaryViewController;

    // Split up the combined primary and detail navigation controller in their component primary and detail view controller lists, but with same ordering.
    NSMutableArray *newPrimaryViewControllers = [NSMutableArray array];
    NSMutableArray *newDetailViewControllers = [NSMutableArray array];
    for (UIViewController *controller in primaryNavController.viewControllers)
    {
    if ([controller respondsToSelector:@selector(shouldDisplayInDetailedView)] && [controller performSelector:@selector(shouldDisplayInDetailedView)])
    {
    [newDetailViewControllers addObject:controller];
    }
    else
    {
    [newPrimaryViewControllers addObject:controller];
    }
    }

    if (newDetailViewControllers.count == 0)
    {
    // If there's no detailed views on the top of the navigation stack, return a blank view (in navigation controller) for detailed side.
    UINavigationController *blankDetailNavController = [[UINavigationController alloc] initWithRootViewController:[[BlankViewController alloc] init]];
    return blankDetailNavController;
    }

    // Set the new primary views.
    primaryNavController.viewControllers = newPrimaryViewControllers;

    // Return the new detail navigation controller and views.
    UINavigationController *detailNavController = [[UINavigationController alloc] init];
    detailNavController.viewControllers = newDetailViewControllers;
    return detailNavController;
    }

    关于uinavigationcontroller - 在 iOS 8 中 UISplitViewController 的主视图中有一个 UINavigationController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26060915/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com