问题
我在演示时注意到一些奇怪的行为UINavigationController
(使用根视图控制器,自然已经推送)UIViewControllerAnimatedTransitioning
打电话期间。
- 如果通话状态栏已启用after当导航控制器出现时,导航控制器会按预期向下移动其视图。但当通话结束时,控制器不会将其视图向后移动,从而在状态栏下方留下 20p 的间隙。
- 如果通话状态栏已启用before呈现控制器时,控制器根本不考虑状态栏,使 44p 高的导航栏的 4p 从 40p 状态栏下方窥视。当通话结束时,控制器会将其视图向下移动以适应正常的 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 bug——毕竟,导航控制器似乎接收到了UIApplicationWillChangeStatusBarFrameNotification
(参见问题的第二点)。如果其他人遇到过这个问题并且找到了更好的方法,我将不胜感激。
我花了太多时间来解决状态栏高度问题,并提出了一个适合我的通用解决方案,我认为也适合您的情况。
首先,状态栏有一些奇怪的地方。
通常高度为 20 点,屏幕通常为 56高8分
“通话中”时,状态栏高 40 点,屏幕 54高8分
状态栏隐藏时,状态栏高0点,屏幕5点6高8分
如果状态栏发生变化但您不更新屏幕的高度,那么计算将关闭,这可以在一些相当大的名称(甚至默认)应用程序中看到。
因此,我提出的解决方案有两个: 1. 创建一个宏来获取调整后的屏幕高度 2. 注册通知以在状态栏更改时更新视图。
这是宏,我建议将它们放入您的prefix
file
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kStatusBarHeight (([[UIApplication sharedApplication] statusBarFrame].size.height == 20.0f) ? 20.0f : (([[UIApplication sharedApplication] statusBarFrame].size.height == 40.0f) ? 20.0f : 0.0f))
#define kScreenHeight (([[UIApplication sharedApplication] statusBarFrame].size.height > 20.0f) ? [UIScreen mainScreen].bounds.size.height - 20.0f : [UIScreen mainScreen].bounds.size.height)
此外,我发现以下通知中心调用在状态栏发生变化时 100% 都适用。
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self.view selector:@selector(layoutSubviews) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)