问题
我注意到在通话期间呈现UINavigationController
(带有根视图控制器,自然已经推送)时出现了一些奇怪的行为。UIViewControllerAnimatedTransitioning
- 如果在呈现导航控制器后启用通话状态栏,则导航控制器会按预期向下移动其视图。但是当通话结束时,控制器不会将其视图重新向上移动,在状态栏下方留下 20p 的间隙。
- 如果在呈现控制器之前启用通话状态栏,则控制器根本不考虑状态栏,留下 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 错误——毕竟,导航控制器似乎收到了UIApplicationWillChangeStatusBarFrameNotification
(参见问题的第二点)。如果其他人遇到此问题并找到了更好的方法,我将不胜感激。