使用自定义模式演示处理呼叫状态栏 [英] Handling In-Call Status Bar with Custom Modal Presentation

查看:130
本文介绍了使用自定义模式演示处理呼叫状态栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在呈现 UINavigationController 时,我注意到一些奇怪的行为(带有根视图控制器) ,在电话通话中已经用 UIViewControllerAnimatedTransitioning 自然推送。

I've noticed some strange behavior when presenting a UINavigationController (with a root view controller, already pushed, naturally) with UIViewControllerAnimatedTransitioning during a phone call.


  • 如果在显示导航控制器之后启用通话中状态栏,导航控制器按预期向下移动其视图。但是当通话结束时,控制器不会将其视图重新向上移动,在状态栏下留下20p的间隙。

  • 如果通话状态栏已启用之前显示控制器,控制器根本没有考虑状态栏,44p高导航栏的4p从40p状态栏下面偷看。当通话结束时,控制器将其视图向下移动以适应正常的20p状态栏。

  • If the in-call status bar is enabled after the the navigation controller is presented, the navigation controller shifts its view down as expected. But when the call is ended, the controller does not shift its view back up, leaving a 20p gap under the status bar.
  • If the in-call status bar is enabled before presenting the controller, the controller does not account for the status bar at all, leaving 4p of the 44p-high navigation bar peeking out from under the 40p status bar. When the call is ended, the controller shifts its view down to accommodate the normal 20p status bar.

*注意:这是在模拟器,由于易于启用/禁用通话中状态栏,但测试人员已在实际手机上观察到此现象。

*note: this was tested on the simulator, due to the ease of enabling/disabling the in-call status bar, but testers have observed this phenomenon on actual phones.

如果状态栏的高度异常,我通过在演示期间调整控制器的框架来解决问题:

I hacked around the issue by adjusting the frame of the controller during presentation, if the status bar was an abnormal height:

@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间隙。

This solution ensures that the navigation bar is below the status bar, but the navigation controller still fails to shift itself back up when the call is ended. So the app is at least usable, but there is an ugly 20p gap above the navigation bar after a call ends.

我是否错过了一些关键步骤来确保导航控制器自己考虑通话状态栏?当呈现内置的模态演示风格时,它工作得很好。

Am I missing some critical step to ensure that the navigation controller accounts for the in-call status bar on its own? It works just fine when presented with the built-in modal presentation style.

在我看来这是一个UIKit错误 - 毕竟,导航控制器似乎收到了 UIApplicationWillChangeStatusBarFrameNotification (参见问题的第二点)。如果有其他人遇到这个问题并找到了更好的方法,我会非常感谢一个解决方案。

In my opinion this smacks of a UIKit bug — after all, the navigation controller seems to receive the UIApplicationWillChangeStatusBarFrameNotification (see second point of The Problem). If anyone else has encountered this problem and has found a better way, I would greatly appreciate a solution.

推荐答案

我花了很多钱太多的时间来到状态栏高度问题,并提出了一个适合我的一般解决方案,我认为也适用于你的情况。

I have spent far too much time on over coming the status bar height issue and have come up with a general solution that works for me and I think will work for your situation as well.

首先,关于状态栏的一些奇怪的事情。

First, a couple things that are odd about the status bar.


  1. 通常高20点,屏幕通常为5 6 8点高

在通话中时,状态栏高40点,屏幕高5 4 高8点

While "in-call", the status bar is 40 points high and the screen is 548 points tall

状态栏隐藏状态酒吧是0分高,屏幕是5 6 8点高

While the status bar is hidden, the status bar is 0 points tall and the screen is 568 points tall

如果状态栏发生更改但您没有更新屏幕的高度,然后计算将关闭,这可以在一些非常大的名称(甚至默认)应用程序中看到。

If the status bar changes but you don't update the height of the screen then the calculations will be off, and this can be seen in some pretty big name (and even default) applications.

所以,我提出的解决方案有两个:1。创建一个宏来获得调整后的屏幕高度2.注册通知以更新视图当状态栏改变时。

So, the solution that I've come up with is two fold: 1. Create a macro to get the adjusted screen height 2. Register a notification to update the view when the status bar changes.

以下是宏,我建议将它们放在前缀文件

Here are the macros, I'd recommend putting these in your 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%的状态栏都会在我的电话中发生变化。

Additionally, here's the notification center call that I've found works for me 100% of the time the status bar changes.

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self.view selector:@selector(layoutSubviews) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];

这篇关于使用自定义模式演示处理呼叫状态栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆