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):
When I enable the wifi hotspot it's still fine:
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.
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
}
}
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
})
}
}
}
}