0

I've a strange issue with the NavigationBar behind the Statusbar.

It only occurs when the default statusbar changes to an "active" statusbar like the one that appears during an active call or a wifi hotspot.

Before the "active" statusbar appears, it looks like this (which is perfectly fine):

enter image description here

When I enable the wifi hotspot it's still fine:

enter image description here

But when I disable the wifi hotspot or end a call the statusbar size shrinks back to its previous size but the ViewController (in this case a UITableViewController) doesn't move up again. It looks like it has a top margin of the statusbars' size. In addition the statusbar is transparent and I can see the background of the view controller below the actual table view controller.

enter image description here

Any ideas on this issue?

Update: I figured out that it's because of a custom modal transition that I've implemented.

It should be a dissolve animation. That's the code:

class DissolveTransition: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
// vars
private var duration: NSTimeInterval = 0.3
private var presenting  = true


// MARK: - UIViewControllerAnimatedTransitioning

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
    return self.duration
}


func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    let destination = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)

    if (destination?.isBeingPresented() == true) {
        self.animatePresentation(transitionContext)
    }
    else {
        self.animateDismissal(transitionContext)
    }
}


private func animatePresentation(transitionContext: UIViewControllerContextTransitioning) {
    self.animateDissolve(transitionContext)
}

private func animateDismissal(transitionContext: UIViewControllerContextTransitioning) {
    self.presenting = false
    self.animateDissolve(transitionContext)
}

private func animateDissolve(transitionContext: UIViewControllerContextTransitioning) {
    let source = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let destination = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let container = transitionContext.containerView()!

    destination.beginAppearanceTransition(true, animated: true)

    let snapshotFromView = source.view.snapshotViewAfterScreenUpdates(true)
    // 1. adding real view at the bottom of the view hierarchy
    if (self.presenting) {
        container.addSubview(destination.view)   
    }

    // 2. adding snapshot of previous view to view hierarchy
    container.addSubview(snapshotFromView)

    // 3. removing (fade) prev snapshot view and show real VC
    UIView.animateWithDuration(self.duration, animations: {
        snapshotFromView.alpha = 0.0
        }, completion: { (finished) in
            if (finished) {
                snapshotFromView.removeFromSuperview()
                container.bringSubviewToFront(destination.view)
            }
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
            destination.endAppearanceTransition()
    })
}


// MARK: - UIViewControllerTransitioningDelegate

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return self
}

func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return self
}

}

Chris
  • 3,057
  • 5
  • 37
  • 63
  • Is it only occurring on that particular controller? Are you implementing any special code related to the status bar in the controller, such as `prefersStatusBarHidden`, `preferredStatusBarStyle` or `preferredStatusBarAnimation`? Do you have any status bar code in the app delegate? Any status bar related stuff in the info.plist? – Kumuluzz Feb 02 '16 at 07:17
  • @Kumuluzz Nope, nothing. No statusBar `appearance` customization, no `preferredStatusBarStyle`, nothing... The only thing that comes to my mind is a custom modal view transition that presents this viewcontroller. But it also occurs in every other viewcontroller _after_ this one. Could it be the custom transition? – Chris Feb 02 '16 at 21:09

1 Answers1

0

I found out that it was because of my custom modal transition that presented this view.

There is an odd bug in iOS that views inside the screen are not resized after the statusBar is changed. This also appears in many well-known Apps.

I fixed it by resizing the views when the statusbar-size changes. Use the following code in your AppDelegate:

    func application(application: UIApplication, willChangeStatusBarFrame newStatusBarFrame: CGRect) {

    if (newStatusBarFrame.size.height < 40) {
        if let window = self.window, subviews = self.window?.subviews {
            for view in subviews {
                UIView.animateWithDuration(0.3, animations: {
                    view.frame = window.bounds
                })
            }
        }
    }
}
Chris
  • 3,057
  • 5
  • 37
  • 63
  • The problem with this method is that you have a bug the other way around when you reactivate the hotspot on the same view, meaning your view will not be pushed again like it is supposed to – thibaut noah Apr 28 '17 at 14:47