SideMenu icon indicating copy to clipboard operation
SideMenu copied to clipboard

iOS 11: Status bar of the transitioned view is white when using menuAnimationTransformScaleFactor

Open frenkelor opened this issue 8 years ago • 56 comments

New Issue Checklist

I have read the guidelines for contributing and I understand:

  • [x] My issue is happening in the latest version of SideMenu.
  • [x] My issue was not solved in the README.
  • [ ] My issue can not be answered on stackoverflow.com.
  • [x] My issue is not a request for new functionality that I am unwilling to build and contribute with a pull request.
  • [x] My issue is reproducible in the demo project.

Issue Description

Status bar of the transitioned view is white see the image below after clicking on the transitioned view the status bar place take over by the view

The issue is reproduced on Xcode 9 GM iPhone 7,8,10 simulator

screen shot 2017-09-13 at 22 23 00

frenkelor avatar Sep 13 '17 19:09 frenkelor

Thanks for reporting. I'm going to roll this into a pending update for Swift 4 with Xcode 9 once it's officially released.

jonkykong avatar Sep 13 '17 21:09 jonkykong

@frenkelor best I can tell, this is a regression or change in functionality in iOS 11 that I cannot easily account for. Whenever a navigation bar is not aligned with the window's top, the height is automatically reduced because it's assumed it does not need to allow space for the status bar.

A work around is to snapshot the main view controller and overlay the snapshot. I have not added this to the library as it would break existing functionality promises (menuPresentingViewControllerUserInteractionEnabled as well as screen rotation ugliness).

Example work-around, placed inside of your UISideMenuNavigationController subclass:

    private weak var screenshot: UIView?

    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let screenshot = presentingViewController?.view.snapshotView(afterScreenUpdates: false) {
            presentingViewController?.view.addSubview(screenshot)
            self.screenshot = screenshot
        }
    }
    
    override open func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        screenshot?.removeFromSuperview()
    }

jonkykong avatar Sep 21 '17 05:09 jonkykong

strange thing is after clicking on the transformed view the one in the right somthing happens the view geting refreshed and the white space disappears

frenkelor avatar Sep 21 '17 11:09 frenkelor

I observed this as well. It appears to update the view based on where the animation will end, not where it begins. Additionally, starting but then cancelling the interactive drag leaves it in the correct state.

The fix I stated above is how a lot of other menu controls get away with this problem. If your app only supports portrait layout you should be in the clear, otherwise you'll have to account for rotation or disable rotation while the menu is displayed.

jonkykong avatar Sep 21 '17 19:09 jonkykong

After desperate hours of trying to solve this issue I got an answer. Just check off translucent checkbox for navigationBar...that worked for me.

calli23 avatar Oct 06 '17 13:10 calli23

@calli23 thanks a ton for that update. I tested this out myself, and while it appears to solve the scrolling jump and white bar, the status bar area still disappears as the main view transforms instantly which isn't smooth.

Additionally, some developers might still be wanting to support translucency on the navigation bar, so I can only call this a partial work-around for now. You can also uncheck extending edges under the top bar for the same effect.

jonkykong avatar Oct 06 '17 17:10 jonkykong

Any update here?

dnosk avatar Oct 27 '17 18:10 dnosk

@dnosk I have not been investigating beyond the initial finds. Have you found a solution?

jonkykong avatar Oct 27 '17 20:10 jonkykong

@jonkykong No solution found yet, "Just check off translucent checkbox for navigationBar...that worked for me" does not work for us :(

dnosk avatar Oct 27 '17 21:10 dnosk

As I mentioned, you can also uncheck extending edges under the top bar for the same effect. Alternatively, you can use the code snippet to substitute a screenshot. You'll also need to prevent screen rotation while the menu is displayed.

jonkykong avatar Oct 27 '17 21:10 jonkykong

There is another possibility:

  1. Use sideMenuWillAppear and do the following
  • Create a new custom UIView with 20px height, x- and y-position both at 0
  • Tag it with a number of your choice
  • Choose your preferred background color
  • Add that view as a subview to your ContentviewController
  1. Use sideMenuWillDissappear and do the following
  • Iterate through your ContentViewControllers subviews
  • If tag number matches your chosen UIView tag number then remove it from superview()

That should do the trick. Some special behavior in case of rotating the device has to be implemented in addition to that workaround.

calli23 avatar Oct 29 '17 12:10 calli23

@calli23 while that will work, it's probably safer (and less code) to use a snapshot to not have to deal with scrolling area changes.

jonkykong avatar Oct 30 '17 02:10 jonkykong

SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear Work for me

kiokumicu avatar Nov 28 '17 08:11 kiokumicu

@kiokumicu what problem does that solve?

jonkykong avatar Nov 28 '17 08:11 jonkykong

@jonkykong 1511863356602

kiokumicu avatar Nov 28 '17 10:11 kiokumicu

Your screenshot does not make use of menuAnimationTransformScaleFactor which is what this bug is about. Setting SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear has no effect on this from my test.

jonkykong avatar Nov 28 '17 10:11 jonkykong

Thank you so much @kiokumicu I spent hours searching for this solution .

salil09 avatar Dec 28 '17 15:12 salil09

Hi guys, I seem to have effectively removed this annoying bug from my own custom implementation of a framework similar to this.

The issue is with UISafeAreaLayoutGuide, which gets removed when UIWindow detects it is no longer needed for a specific UIViewController, such as here where the view controller gets transformed into a smaller scale thus not in range of the safe area insets. The way I solved it in my own implementation is by adding custom safearea insets, effectively supplementing those that is originally given to us automatically. These area insets is inserted at the beginning of the animation:

private func addSafeInsets(forVC vc: UIViewController) { if #available(iOS 11.0, *) { print(vc.view.safeAreaLayoutGuide.layoutFrame) vc.additionalSafeAreaInsets = UIEdgeInsets(top: vc.view.safeAreaLayoutGuide.layoutFrame.origin.y, left: 0.0, bottom: 0.0, right: 0.0) } else { // Fallback on earlier versions } }

And should be removed as soon as the dismissal animation is started:

private func removeSafeInsets(forVC vc: UIViewController) { if #available(iOS 11.0, *) { print(vc.view.safeAreaLayoutGuide.layoutFrame) vc.additionalSafeAreaInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0) } else { // Fallback on earlier versions } }

Now I hope these small snippets can help the code creator of this framework, thus it might not if it is build in an entirely different way than mine. Although im just so happy to have finally solved this issue for myself.

EmilsenLind avatar Mar 10 '18 13:03 EmilsenLind

@EmilsenLind thank you for reporting this. My initial tests do seem to show this can resolve the issue, though more testing needs to be done and I'm concerned that the solution will cause other bugs.

jonkykong avatar Mar 12 '18 20:03 jonkykong

Update:

I've spent a few hours trying to correct for this behavior and am getting very inconsistent results across the following permutations:

  • Interactive (gesture based) vs. non-interactive display
    • Canceling interactive displays
  • Transforms:
    • No transform (menuAnimationTransformScaleFactor == 1)
    • Shrinking transforms (menuAnimationTransformScaleFactor < 1)
    • Growing transforms (menuAnimationTransformScaleFactor > 1)
  • Screen rotation after menu is displayed

I've tried transforming the view.layer instead of the views directly with a minor increase in success, but still no clean and consistent working solutions.

Rather than submit an incomplete solution and get new bug reports, I have committed my progress on branch #258-Fixes if someone else wants to try resolving it for all of the combinations above.

jonkykong avatar May 24 '18 01:05 jonkykong

when i first open sidemenu, the result same image bellow image after first click, click sidemenu button again. It's ok image I setup sidemenu same above: SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear why? I'm using ipad, and ios 10.

hangocanh2303 avatar Jun 13 '18 08:06 hangocanh2303

Does this happen in the example project? If not, then you are most likely doing something wrong.

On Wed, Jun 13, 2018 at 1:36 AM Hà Ngọc Anh [email protected] wrote:

when i first open sidemenu, the result same image bellow [image: image] https://user-images.githubusercontent.com/19758537/41339501-2996f31a-6f1f-11e8-90b5-3b9c6a39aad2.png after first click, click sidemenu button again. It's ok [image: image] https://user-images.githubusercontent.com/19758537/41339547-4db5214a-6f1f-11e8-9579-1b3ee1af0a72.png I setup sidemenu same above: SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear why? I'm using ipad, and ios 10.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jonkykong/SideMenu/issues/258#issuecomment-396859961, or mute the thread https://github.com/notifications/unsubscribe-auth/AFdl_5j-FNMUmoil24vY2YIBLGT5DPQEks5t8M8igaJpZM4PWnL- .

jonkykong avatar Jun 13 '18 08:06 jonkykong

@jonkykong I create sidemenu in code, not in storyboard This is my code setup // side menu add private func setupSideMenu() { let menuLeftNavigationController = UISideMenuNavigationController(rootViewController: SideMenuVC()) SideMenuManager.default.menuLeftNavigationController = menuLeftNavigationController SideMenuManager.default.menuFadeStatusBar = true SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear SideMenuManager.default.menuAddPanGestureToPresent(toView: self.navigationBar) SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.view) SideMenuManager.default.menuShadowColor = .white SideMenuManager.default.menuShadowRadius = 0 SideMenuManager.default.menuShadowOpacity = 255 // fix black status bar //SideMenuManager.defaultManager.menuAnimationBackgroundColor = UIColor.rgb(red: 49, green: 48, blue: 49) SideMenuManager.default.menuPresentMode = .menuSlideIn SideMenuManager.defaultManager.menuPushStyle = .subMenu

}

And this is my code i call when menu button tapped: @objc private func menuButtonTapped() { print("show slide menu here") present(SideMenuManager.defaultManager.menuLeftNavigationController!, animated: true, completion: nil)

}

hangocanh2303 avatar Jun 15 '18 08:06 hangocanh2303

menuFadeStatusBar uses the menuAnimationBackgroundColor.

jonkykong avatar Jun 15 '18 20:06 jonkykong

It's not working image //SideMenuManager.default.menuAnimationBackgroundColor = true SideMenuManager.default.menuAnimationBackgroundColor = UIColor.green image

hangocanh2303 avatar Jun 16 '18 03:06 hangocanh2303

Based on your example, it's working exactly as intended.

jonkykong avatar Jun 16 '18 05:06 jonkykong

** image ** I want it show similar above image, but it show similar bellow when first open side menu image

hangocanh2303 avatar Jun 18 '18 01:06 hangocanh2303

It works fine. Turn of fade menu status bar.

On Sun, Jun 17, 2018 at 9:46 PM Hà Ngọc Anh [email protected] wrote:

** [image: image] https://user-images.githubusercontent.com/19758537/41514737-71f0b490-72d3-11e8-8773-41e96b184aaf.png ** I want it show similar above image, but it show similar bellow when first open side menu [image: image] https://user-images.githubusercontent.com/19758537/41514821-20d9bfc4-72d4-11e8-8d27-ed4cbf5002b4.png

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jonkykong/SideMenu/issues/258#issuecomment-397922962, or mute the thread https://github.com/notifications/unsubscribe-auth/AFdl_12itxWJtSrOJMKuu_KNF1RqyyPsks5t9waLgaJpZM4PWnL- .

jonkykong avatar Jun 18 '18 03:06 jonkykong

ok, i solved this issue reason is: statusBarBackgroundView.backgroundColor = UIColor.rgb(red: 251, green: 64, blue: 0) I set background color for status bar in AppDelegate. Many thanks @jonkykong

hangocanh2303 avatar Jun 18 '18 06:06 hangocanh2303

just implement UISideMenuNavigationControllerDelegate `extension ViewController: UISideMenuNavigationControllerDelegate {

func sideMenuWillAppear(menu: UISideMenuNavigationController, animated: Bool) {
    print("SideMenu Appearing! (animated: \(animated))")
    SideMenuManager.default.menuAnimationBackgroundColor = UIColor.clear
}

}`

yanaMyn avatar Jul 24 '18 13:07 yanaMyn