Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do layout to handle in-call (double-height) status bar for custom presented view controller in iOS 8?

In iOS 7, I was able to handle layout for a custom presented view controller to also account for the in-call status bar by adding constraints where the presented view controller has the same center and the same width and height as the presenting view controller. This was preferred to using auto-resizing for the width and height because, otherwise, when the in-call status bar goes away, the presented view controller would remain pushed down by 20 points from the top for some reason.

In iOS 8, however, this trick doesn't work anymore. For one thing, I found through experimentation that the presenting view controller does not seem to necessarily be in the container view, so I can't add those constraints to the container view. (The sample code for the "A Look Inside Presentation Controllers" 2014 WWDC video does not put the presenting view controller in there.) It seems that having the presented view controller filling the container view using either auto-layout or auto-resizing would work, but I found that the container view itself may remain pushed down by 20 points when the in-call status bar disappears (which was not the case in iOS 7).

I've been playing around with the "A Look Inside Presentation Controllers" sample code, but even this code does not handle the in-call status bar correctly. (I'm still trying to get a handle on the new UIPresentationController API, by the way.)

like image 577
ememem Avatar asked Sep 17 '14 05:09

ememem


1 Answers

What worked for me was adding an observer for UIApplicationWillChangeStatusBarFrameNotification, then finding the transitionContext.containerView() and updating the frame. I noticed when view debugging that the transitionContext.containerView() frame wasn't updated when going back to the normal status bar height.

func willChangeStatusBarFrame(notification: NSNotification)
{
    if let userInfo = notification.userInfo
    {
        if let value = userInfo[UIApplicationStatusBarFrameUserInfoKey] as? NSValue
        {
            let statusBarFrame = value.CGRectValue()
            let transitionView = UIApplication.sharedApplication().delegate!.window!!.subviews.last! as UIView
            var frame = transitionView.frame
            frame.origin.y = statusBarFrame.height-20
            frame.size.height = UIScreen.mainScreen().bounds.height-frame.origin.y
            UIView.animateWithDuration(0.35) {
                transitionView.frame = frame
            }
        }
    }
}
like image 160
Tom King Avatar answered Nov 15 '22 14:11

Tom King