Handling In-Call Status Bar with Custom Modal Presentation

守給你的承諾、 提交于 2019-12-02 15:47:56

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. It's normally 20 points tall and the screen is normally 568 points tall

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

  3. 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.

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)

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];

I had the same issue and the problem was with the view that I was presenting which was automatically adjusted by 20pt because of in-call bar. However since I insert the view into container, I had to reset the frame to match container's bounds.

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIView* destinationView = [transitionContext viewForKey:UITransitionContextToViewKey];
    UIView* container = transitionContext.containerView;

    // Make sure destination view matches container bounds
    // This is necessary to fix the issue with in-call bar
    // which adjusts the view's frame by 20pt.
    destinationView.frame = container.bounds;

    // Add destination view to container
    [container insertSubview:destinationView atIndex:0];

    // [reducted]
}

Just set the frame in layoutSubviews as it is called when the status bar height changes. In general as a rule of thumb, do all frame setting in layoutSubviews only.

Here is a workaround I put in my app delegate that fixed the problem for me:

- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame
{
    if (newStatusBarFrame.size.height < 40) {
        for (UIView *view in self.window.subviews) {
            view.frame = self.window.bounds;
        }
    }
}

I had the same issue and I fixed it by call update frame view, so i get height status bar. My problem was solved.

 UIView *toViewSnapshot = [toView resizableSnapshotViewFromRect:toView.frame afterScreenUpdates:YES withCapInsets:UIEdgeInsetsZero];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!