问题
在电话呼叫期间,当用 UIViewControllerAnimatedTransitioning
呈现 UINavigationController
(带有根视图控制器,已经自然推送)时,我注意到了一些奇怪的行为 .
-
如果在显示导航控制器后启用了呼叫状态栏,导航控制器将按预期向下移动其视图 . 但是当呼叫结束时,控制器不会将其视图向上移动,在状态栏下留下20p的间隙 .
-
如果在显示控制器之前启用了通话中状态栏,则控制器根本不会考虑状态栏,而是从40p状态栏下方留下4p的44p高导航栏 . 通话结束后,控制器将其视图向下移动以适应正常的20p状态栏 .
*注意:这是在模拟器上测试的,因为它很容易启用/禁用通话状态栏,但测试人员在实际手机上观察到了这种现象 .
我的(部分)解决方法
如果状态栏是异常高度,我通过在演示期间调整控制器的框架来解决问题:
@interface CustomAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation CustomAnimationController
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *container = [transitionContext containerView];
CGRect frame = [transitionContext finalFrameForViewController:toController];
if (CGRectEqualToRect(frame, CGRectZero))
{
// In my experience, the final frame is always a zero rect, so this is always hit
UIEdgeInsets insets = UIEdgeInsetsZero;
// My "solution" was to inset the container frame by the difference between the
// actual status bar height and the normal status bar height
insets.top = CGRectGetHeight([UIApplication sharedApplication].statusBarFrame) - 20;
frame = UIEdgeInsetsInsetRect(container.bounds, insets);
}
toController.view.frame = frame;
[container addSubview:toController.view];
// Perform whiz-bang animation here
}
@end
此解决方案确保导航栏位于状态栏下方,但导航控制器仍然无法在呼叫结束时自行切换 . 因此该应用程序至少可以使用,但在通话结束后导航栏上方有一个难看的20p间隙 .
有更好的方法吗?
我是否遗漏了一些关键步骤以确保导航控制器自己考虑通话状态栏?当呈现内置的模态演示风格时,它工作得很好 .
在我看来这是一个UIKit错误 - 毕竟,导航控制器似乎收到 UIApplicationWillChangeStatusBarFrameNotification
(见问题的第二点) . 如果其他人遇到这个问题并找到了更好的方法,我将非常感谢一个解决方案 .
5 回答
我花了太多时间来处理状态栏高度问题,并提出了一个适用于我的通用解决方案,我认为也适用于您的情况 .
首先,关于状态栏的一些奇怪的事情 .
通常高20点,屏幕通常高5点,高度为8点
在"in-call"时,状态栏为40点高,屏幕为5 4 8点高
状态栏隐藏时,状态栏高0点,屏幕高5点 6 8点
如果状态栏发生更改但您没有更新屏幕的高度,则计算将关闭,这可以在一些非常大的名称(甚至默认)应用程序中看到 .
因此,我提出的解决方案有两个方面:1 . 创建宏以获得调整后的屏幕高度2.在状态栏更改时注册通知以更新视图 .
以下是宏,我建议将它们放在
prefix
文件中此外,这是我发现的通知中心呼叫,100%的状态栏更改时 .
我遇到了同样的问题,问题在于我所呈现的视图因为在电话栏中而被自动调整了20pt . 但是,因为我将视图插入容器,我不得不重置框架以匹配容器的边界 .
只需在状态栏高度更改时调用layoutSubviews中的框架 . 通常,根据经验,只在layoutSubviews中进行所有框架设置 .
这是我在我的应用委托中添加的解决方法,为我解决了问题:
我有同样的问题,我通过调用更新框架视图修复它,所以我得到高度状态栏 . 我的问题解决了 .