gpt4 book ai didi

IOS8 SplitVC + TabBarController + NavigationController

转载 作者:可可西里 更新时间:2023-11-01 06:05:41 31 4
gpt4 key购买 nike

我正在做一个使用大小类的通用应用程序,我正在尝试在主视图/主视图中使用带有 TabBarController 的 SplitView。在添加 splitView 之前一切正常,但现在应用程序崩溃了(原因取决于 View 的层次结构)。

所以我尝试了从 Apple SplitView 模板开始的相同 Storyboard,并在其主视图/主视图上添加了一个 TabBarController ...同样的问题。

层次结构 - TabBarController 中的嵌入式主 NavigationController:SplitVC (Master) > TabBarController > NavigationController > TableViewSplitVC(详细信息)> NavigationController > 查看

在 AppDelegate.m 中添加此代码(如此处所示 stackoverflow questions ios8-tabbarcontroller... 以防止以模态方式呈现 DetailView):

- (BOOL)splitViewController:(UISplitViewController *)splitViewController showDetailViewController:(UIViewController *)vc sender:(id)sender {
NSLog(@"UISplitViewController collapsed: %d", splitViewController.collapsed);

if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
if (splitViewController.collapsed) {
UITabBarController *master = (UITabBarController *) splitViewController.viewControllers[0];
UINavigationController *masterNavigationController = (UINavigationController *)master.selectedViewController;
UINavigationController *destinationNavigationController = (UINavigationController *)vc;

// push detail view on the navigation controller
[masterNavigationController pushViewController:[destinationNavigationController.viewControllers lastObject] animated:YES];

return YES;
}
}

return NO;
}

它工作正常......除非你在 iPhone6 Plus 中模拟,在那种情况下,在纵向开始并选择一行后,如果你在横向旋转,我会看到详细 View 作为主要和次要 View 。

如果在 iPhone 的纵向模式下不添加此代码,详细 View 将以模态方式呈现,当然也没有导航按钮。

编辑

经过多次尝试并借助一些外部帮助,我已经朝着解决方案迈出了一些步伐。

短版(请参阅长版以了解为什么必须这样做)

该问题的正确解决方案是继承 TabBarController 并使其支持某些方法:

@implementation MyTabBarController

- (void)showViewController:(UIViewController *)vc sender:(id)sender
{
if ([self.selectedViewController isKindOfClass:UINavigationController.class])
[self.selectedViewController showViewController:vc sender:sender];
else
[super showViewController:vc sender:sender];
}

- (UIViewController*)separateSecondaryViewControllerForSplitViewController:(UISplitViewController *)splitViewController
{
return [self.selectedViewController separateSecondaryViewControllerForSplitViewController:splitViewController];
}

- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
[self.selectedViewController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}

现在我遇到了 viewControllers 堆栈的问题:对于 iPhone6Plus(唯一支持水平常规和紧凑型的),如果在横向模式下更改选项卡而不选择行(因此 detailView 仍然是用于上一个选项卡),然后纵向旋转。

我知道我必须实现分离和折叠方法以正确管理 View 堆栈,但我不知道如何操作。有人可以帮忙吗?

Long version (SplitViewController behaviour)

Normally a split view controller and a navigation controller work together to ensure that a call to -showDetailViewController:sender: from a view controller that is contained within the split view controller results in the new detail view controller being pushed onto the navigation stack (when in a horizontally compact environment). To do this, UISplitViewController overrides -showDetailViewController:sender: and, if horizontally compact, calls its master view controller's -showViewController:sender: method. UINavigationController overrides -showViewController:sender: and pushes the incoming view controller onto the navigation stack.

UITabBarController however does not override -showViewController:sender: and so it inherits the default implementation which presents the incoming view controller modally. To work around this I have to subclass UITabBarController and override -showViewController:sender: to forward to the tab bar controller's selectedViewController if the selectedViewController is a navigation controller.

Furthermore, when a split view controller transitions from a compact to horizontal size class to a regular horizontal size class, the split view controller first sends a -splitViewController:separateSecondaryViewControllerFromPrimaryViewController: message to its delegate. The delegate can implement this method and handle the separation itself, returning the detail view controller. If the delegate does not implement this method, or if the implementation returns nil, the split view controller sends a -separateSecondaryViewControllerForSplitViewController: message to its primary view controller. The primary view controller should implement this method to handle the separation. The UINavigationController does implement -separateSecondaryViewControllerForSplitViewController:. It's implementation pops the top view controller off the navigation stack and returns it. Because I am using a tab bar controller as the primary view controller, I must implement -separateSecondaryViewControllerForSplitViewController: and handle the separation by myself.

Also I need to implement my own collapsing logic. When a split view controller transitions from a regular to horizontal size class to a compact horizontal size class, the split view controller first sends a -splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: message to its delegate. The delegate can implement this method and handle the collapse itself. If the delegate does not implement this method, the split view controller sends a -collapseSecondaryViewController:forSplitViewController: message to its primary view controller. The primary view controller should implement this method to handle the separation.

UINavigationController does implement -collapseSecondaryViewController:forSplitViewController:. It's implementation pushes the secondary view controller onto the navigation stack. Because I am using a tab bar controller as the primary view controller, I must implement -collapseSecondaryViewController:forSplitViewController: and handle the collapse by myself.

最佳答案

所以,我发现了一些有用的东西,即使这不是标准行为:

- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
[self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}

这相当于在 splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: 委托(delegate)方法中始终返回 YES。像这样,您总是丢弃辅助 Controller 。希望这可以帮助某人。

关于IOS8 SplitVC + TabBarController + NavigationController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31329552/

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