Short version:
I am having a problem with auto layout top layout guide when used in conjunction with custom transition and UINavigationController in iO
I solved this by fixing the height constraint of the topLayoutGuide. Adjusting edgesForExtendedLayout wasn't an option for me, as I needed the destination view to underlap the navigation bar, but also to be able to layout subviews using topLayoutGuide.
Directly inspecting the constraints in play shows that iOS adds a height constraint to the topLayoutGuide with value equal to the height of the navigation bar of the navigation controller. Except, in iOS 7, using a custom animation transition leaves the constraint with a height of 0. They fixed this in iOS 8.
This is the solution I came up with to correct the constraint (it's in Swift but the equivalent should work in Obj-C). I've tested that it works on iOS 7 and 8.
func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
let fromView = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!.view
let destinationVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
destinationVC.view.frame = transitionContext.finalFrameForViewController(destinationVC)
let container = transitionContext.containerView()
container.addSubview(destinationVC.view)
// Custom transitions break topLayoutGuide in iOS 7, fix its constraint
if let navController = destinationVC.navigationController {
for constraint in destinationVC.view.constraints() as [NSLayoutConstraint] {
if constraint.firstItem === destinationVC.topLayoutGuide
&& constraint.firstAttribute == .Height
&& constraint.secondItem == nil
&& constraint.constant == 0 {
constraint.constant = navController.navigationBar.frame.height
}
}
}
// Perform your transition animation here ...
}