handsomecode/InteractiveSideMenu

UINavigationBar resizing issue - iOS11, Swift 3, Xcode9

idikic opened this issue · 9 comments

Hello guys, first off very nice library!

Intro

  • Xcode 9 GM
  • Swift 3.2
  • iOS 11
  • Simulator and device

Issue

If we embed UINavigationController as child view to MenuContainerViewController on iOS11, there is an issue with UINavigationBar height, when closing the side menu. When interaction starts, UINavigationBar will resize itself from the top to the size that will be 20pt less then the size of child view, so you will be able to see the view behind.

This can be only seen on iOS11. I tried various stuff to fix it but without much success. If we hide navigation bar, or if the status bar is hidden, the issue will disappear.

I'm also attaching a project so that you can check it out.

InteractiveSideMenu-Issue.zip

Thank you for so detailed question. We will take a look at it a little bit later.

Thanks :)

i also have this issue

It looks like CGAffineTransform(scaleX, y) of ViewController's view works not correctly with NavigationBar in iOS 11. I'm going to report a bug to Apple.

With contentScale = 1 for iOS 11 users SideMenu works correctly. I'll keep you posted.

Thanks for input @okonor!

Getting the same issue. @okonor Did Apple ever get back to you? I know they are not huge fans of side menus to begin with. Did you find a fix? I took the status bar out completely to resolve the issue in the short-term while looking for a solution.

There appears to be a critical range with the contentScale property of the TransitionOptions that causes the odd behavior. When using a contentScale of 0.87 - 0.90, there seems to be an issue with the content controller's view not getting its safeAreaInsets set properly. From testing, I can only see it affecting those four values in that range.

I will continue to look into the issue but, for now, I will update the default value of the contentScale to be outside of this range so that the library works on iOS 11 by default

@idikic @jackdem @mtashley
Try using 2.2.1. The default contentScale was changed to be outside of the affected range that causes the safeAreaInsets not to be set properly on the content controller.

I will still be looking into this issue to see how I can make things work no matter the contentScale setting but this is the best I can do for now.

A possible work around is to anchor a 0px tall view to the top of the view, lets call this view topAnchorView.

Set up top anchor with the following constraints:

  • Height = 0px
  • Width = superview.width
  • CenterX = superview.CenterX
  • TopAnchor = topSafeArea -> you will need to create an outlet for this so we can deactivate it later
    @IBOutlet weak var safeAreaTopConstraint: NSLayoutConstraint!

You can then anchor anything that needs a top anchor to topAnchorView

In your controller, add a topConstraintAnchor variable
var topSpaceContraint: NSLayoutConstraint!

Finally, in viewDidAppear do

       // Only do this once
        if topSpaceContraint == nil {

        var topPadding: CGFloat = 0

       // setup the top padding to be equal to the current top padding
        if #available(iOS 11.0, *) {
            topPadding = view.safeAreaInsets.top
        } else {
            topPadding = topLayoutGuide.length
        }
            topSpaceContraint = searchBar.topAnchor.constraint(equalTo: topAnchorView.superview!.topAnchor, constant: topAnchorView.frame.origin.x + topPadding)
            safeAreaTopConstraint.isActive = false
            topSpaceContraint.isActive = true
        }

What are we doing?

Create a view that acts as the new top anchor, this will be the "source of all true" with regards to top layouts

Anchor everything to that view

Replace the safe area topAnchor with a controller.view.topAnchor during the first appearance(Before the sidebar interferes!)