gpt4 book ai didi

ios - UITabBarController + UINavigationController 和更多选项卡黑屏问题

转载 作者:行者123 更新时间:2023-12-01 18:47:53 27 4
gpt4 key购买 nike

我目前正在对我的一个应用程序进行更新,并且遇到了一个与 UITabBarController 相关的非常奇怪的问题。

在我的 Storyboard中,我有大约 8 个 View Controller ,在我的 UITabBarController 子类中,我添加了另外 4 个以编程方式加载的 View Controller 。大多数这些 View 都需要 UINavigationController 以在旋转时保持一致性,因为一些 View 从“更多”选项卡进入主栏,为了做到这一点,我将它们嵌入到 UINavigationController 中。

如果您选择纵向 View 6,并且当 View 在选项卡栏中获得自己的按钮时,旋转 UINavigationController 会变黑,但是当它返回“更多”时, View 会返回。在我对这些的调查中,似乎 UINavigationController 丢失了 UIViewController 作为它的 Root View Controller 。

在未进入“更多”标签的 View 上按预期工作:imgur.com/gVB8wTF

如果 View 来自“更多”选项卡,则会出现黑屏:http://imgur.com/WaoNoL1

我做了一个有这个问题的快速示例项目:https://github.com/joshluongo/UITabBarController-Issues

有想法该怎么解决这个吗?

最佳答案

我遇到了同样的问题。

我能够想出一个非常有效的解决方法。我已经把它推到了 Github 上:https://github.com/jfahrenkrug/UITabBarControllerMoreBugWorkaround

欢迎任何改进。

发生该错误是因为您的 UINavigationController 的堆栈已从中删除并放入私有(private) UIMoreNavigationController。但是在旋转回常规宽度时,该堆栈未正确放回其原始 UINavigationViewController。

解决方案是继承 UITabBarController 并替换它的 willTransitionToTraitCollection:withTransitionCoordinator:有了这个:

- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
//#define MORE_TAB_DEBUG 1
#ifdef MORE_TAB_DEBUG
#define MoreTabDLog(fmt, ...) NSLog((@"[More Tab Debug] " fmt), ##__VA_ARGS__);
#else
#define MoreTabDLog(...)
#endif

MoreTabDLog(@"-- before willTransitionToTraitCollection");

/*
There is a bug when going in and out of the compact size class when a tab bar
controller has more than 5 tabs. See http://www.openradar.me/25393521

It comes down to this: When you have more than 5 tabs and a view controller on a tab
beyond the 4th tab is a UINavigationController, you have a problem.
When you are on this tab in compact and push one or more VCs onto the stack and then
change back to regular width, only the top most view controller will be added back onto the
stack.

This happens because the stack of your UINavigationController is taken out of that NavVC and put
into the private UIMoreNavigationController. But upon rotating back to regular, that stack is not
correctly put back into your own NavVC.

We have 3 cases we have to handle:

1) We are on the "More" tab in compact and are looking at the UIMoreListController and then change to
regular size.
2) While in compact width, we are on a tab greater than the 4th and are changing to regular width.
3) While in regular width, we are on a tab greater than the 4th and are changing to compact width.
*/

if ((self.traitCollection.horizontalSizeClass != newCollection.horizontalSizeClass) ||
(self.traitCollection.verticalSizeClass != newCollection.verticalSizeClass))
{
/*
Case 1: We are on the "More" tab in compact and are looking at the UIMoreListController and then change to regular size.
*/
if ([self.selectedViewController isKindOfClass:[UINavigationController class]] && [NSStringFromClass([self.selectedViewController class]) hasPrefix:@"UIMore"]) {
// We are on the root of the MoreViewController in compact, going into regular.
// That means we have to pop all the viewControllers in the MoreViewController to root
#ifdef MORE_TAB_DEBUG
UINavigationController *moreNavigationController = (UINavigationController *)self.selectedViewController;

UIViewController *moreRootViewController = [moreNavigationController topViewController];

MoreTabDLog(@"-- going OUT of compact while on UIMoreList");
MoreTabDLog(@"moreRootViewController: %@", moreRootViewController);
#endif

for (NSInteger overflowVCIndex = 4; overflowVCIndex < [self.viewControllers count]; overflowVCIndex++) {
if ([self.viewControllers[overflowVCIndex] isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)self.viewControllers[overflowVCIndex];
MoreTabDLog(@"popping %@ to root", navigationController);
[navigationController popToRootViewControllerAnimated:NO];
}
}
} else {
BOOL isPotentiallyInOverflow = [self.viewControllers indexOfObject:self.selectedViewController] >= 4;

MoreTabDLog(@"isPotentiallyInOverflow: %i", isPotentiallyInOverflow);

if (isPotentiallyInOverflow && [self.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *selectedNavController = (UINavigationController *)self.selectedViewController;
NSArray<UIViewController *> *selectedNavControllerStack = [selectedNavController viewControllers];

MoreTabDLog(@"Selected Nav: %@, selectedNavStack: %@", selectedNavController, selectedNavControllerStack);
UIViewController *lastChildVCOfTabBar = [[self childViewControllers] lastObject];

if ([lastChildVCOfTabBar isKindOfClass:[UINavigationController class]] && [NSStringFromClass([lastChildVCOfTabBar class]) hasPrefix:@"UIMore"]) {
/*
Case 2: While in compact width, we are on a tab greater than the 4th and are changing to regular width.

We are going OUT of compact
*/
UINavigationController *moreNavigationController = (UINavigationController *)lastChildVCOfTabBar;

NSArray *moreNavigationControllerStack = [moreNavigationController viewControllers];

MoreTabDLog(@"--- going OUT of compact");
MoreTabDLog(@"moreNav: %@, moreNavStack: %@, targetNavStack: %@", moreNavigationController, moreNavigationControllerStack, selectedNavControllerStack);

if ([moreNavigationControllerStack count] > 1) {
NSArray *fixedTargetStack = [moreNavigationControllerStack subarrayWithRange:NSMakeRange(1, moreNavigationControllerStack.count - 1)];

MoreTabDLog(@"fixedTargetStack: %@", fixedTargetStack);

dispatch_async(dispatch_get_main_queue(), ^{
NSArray *correctVCList = [NSArray arrayWithArray:self.viewControllers];
[selectedNavController willMoveToParentViewController:self];
[selectedNavController setViewControllers:fixedTargetStack animated:NO];
// We need to do this because without it, the selectedNavController doesn't
// have a parentViewController anymore.
[self addChildViewController:selectedNavController];

// We need to do this because otherwise the previous call will cause the given
// Tab to show up twice in the UIMoreListController.
[self setViewControllers:correctVCList];
});
} else {
MoreTabDLog(@"popping to root");
dispatch_async(dispatch_get_main_queue(), ^{
[selectedNavController popToRootViewControllerAnimated:NO];
});
}
} else {
/*
Case 3: While in regular width, we are on a tab greater than the 4th and are changing to compact width.

We are going INTO compact
*/

MoreTabDLog(@"-- going INTO compact");

if ([selectedNavControllerStack count] > 0) {
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
// no op
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
UIViewController *parentViewControllerOfTopVC = [[selectedNavControllerStack lastObject] parentViewController];

MoreTabDLog(@"parentViewControllerOfTopVC: %@", parentViewControllerOfTopVC);

if ([parentViewControllerOfTopVC isKindOfClass:[UINavigationController class]] && [NSStringFromClass([parentViewControllerOfTopVC class]) hasPrefix:@"UIMore"]) {
UINavigationController *moreNavigationController = (UINavigationController *)parentViewControllerOfTopVC;

NSArray *moreNavigationControllerStack = [moreNavigationController viewControllers];

BOOL isOriginalRootVCInMoreStack = [moreNavigationControllerStack containsObject:[selectedNavControllerStack firstObject]];

MoreTabDLog(@"moreNav: %@, moreNavStack: %@, isOriginalRootVCInMoreStack: %i", moreNavigationController, moreNavigationControllerStack, isOriginalRootVCInMoreStack);

if (!isOriginalRootVCInMoreStack) {
NSArray *fixedMoreStack = [@[moreNavigationControllerStack[0]] arrayByAddingObjectsFromArray:selectedNavControllerStack];

MoreTabDLog(@"fixedMoreStack: %@", fixedMoreStack);

[selectedNavController setViewControllers:selectedNavControllerStack animated:NO];

dispatch_async(dispatch_get_main_queue(), ^{
[moreNavigationController setViewControllers:fixedMoreStack animated:NO];
});
}
}
}];
}
}
}
}

}

[super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];

MoreTabDLog(@"-- after willTransitionToTraitCollection");
}

享受!

约翰内斯

关于ios - UITabBarController + UINavigationController 和更多选项卡黑屏问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33534464/

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