iOS7 Side menu status bar color transition. As in the iOS7 Facebook App

前端 未结 3 1047
清酒与你
清酒与你 2021-02-01 10:53

The iOS7 Facebook App has a right side menu that can be shown by swiping right to left or clicking on the upper right button. When this menu is opened the there is a color trans

相关标签:
3条回答
  • 2021-02-01 11:27

    You can use this awesome slide menu library

    https://github.com/arturdev/AMSlideMenu

    In this demo project you can see how to do that by writing 4 lines of code.

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        // Setting navigation's bar tint color
        self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:@"#365491" alpha:1];
    
        // Making view with same color that navigation bar
        UIView *statusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 20)];
        statusBarView.backgroundColor = [UIColor colorWithHex:@"#365491" alpha:1];
    
        // Replace status bar view with created view and do magic :)
        [[self mainSlideMenu] fixStatusBarWithView:statusBarView];
    }
    
    0 讨论(0)
  • 2021-02-01 11:34

    I managed to find a very simple, elegant way to do this, that mimics the Facebook app functionality perfectly.

    Here's my approach:

    • Create view with status bar frame
    • Set view background color to black, opacity to 0
    • Add view as subview to any root view (you need a view that will cover both the center view and the menus, so that it won't be confined to any single view - a good option for this is the container view controller used by your menu controller implementation)
    • Set view's opacity in your menu controller implementation's menu animation method

    Here's my specific implementation, using MMDrawerController:

    I subclassed MMDrawerController (I actually already had a subclass for using MMDrawerController with storyboards), and added this code to the class's init method:

    // Setup view behind status bar for fading during menu drawer animations
    if (OSVersionIsAtLeastiOS7()) {
        self.statusBarView = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] statusBarFrame]];
        [self.statusBarView setBackgroundColor:[UIColor blackColor]];
        [self.statusBarView setAlpha:0.0];
        [self.view addSubview:self.statusBarView];
    }
    
    // Setup drawer animations
    __weak __typeof(&*self) weakSelf = self; // Capture self weakly
    
    [self setDrawerVisualStateBlock:^(MMDrawerController *drawerController, MMDrawerSide drawerSide, CGFloat percentVisible) {
        MMDrawerControllerDrawerVisualStateBlock block;
        block = (drawerSide == MMDrawerSideLeft) ? [MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:15.0] : nil; // Right side animation : Left side animation
        if(block){
            block(drawerController, drawerSide, percentVisible);
        }
        [weakSelf.statusBarView setAlpha:percentVisible];    // THIS IS THE RELEVANT CODE
    }];
    

    I also added self.statusBarView as a private property.

    • The first section of code creates a view, configures it, and adds it as a subview of the MMDrawerController subclass's view. The OSVersionIsAtLeastiOS7() method is a custom method that simplifies the check to see if the device is running iOS 7 (if it isn't, your custom view will show up below the status bar, which you don't want).

    • The second section of code is MMDrawerController's setDrawerVisualStateBlock method, which sets the animations code to be performed when a menu is being opened and closed. The first few lines of code are boilerplate code that sets one of the prebuilt animations blocks to each menu (I wanted parallax on the left, but nothing on the right). The relevant code is the last line of the block: [weakSelf.statusBarView setAlpha:percentVisible];, which sets the status bar view's opacity to match the percentage that the menu is currently open. This allows for the smooth cross animation you see in the Facebook app. You'll also notice I've assigned self to a variable weakSelf, so as to avoid the "retain cycle" compiler warning.

    This is my specific approach using MMDrawerController and a subclass, which I did more for convenience because I already had the subclass in place, than because it is necessarily the best approach or the only way to do it. It could probably be implemented in several other ways, using MMDrawerController without a subclass, or using any other side-drawer menu implementation.

    The ending result is a smooth fading to black animation behind the status bar, exactly as you see in the new Facebook app.

    0 讨论(0)
  • 2021-02-01 11:52

    I've been trying to accomplish the same thing. The method I am using to do this is based on the following concepts:

    1. A background image with a height of 64 points will fill both the UINavigationBar and the UIStatusBar.
    2. A background image with a height of 44 points will fill the UINavigationBar and leave the UIStatusBar black.
    3. You can add an subview to the top of the current navigationController's view and it will sit underneath the UIStatusBar.

    So, first, you need to create two images with your desired UINavigationBar look:

    A 640x128px image to cover navigation bar and status bar (ImageA)

    Image that covers both the UINavigationBar and the UIStatusBar

    And a 640x88px image to cover the navigation bar but leave the status bar black (ImageB).

    enter image description here

    In the application:didFinishLaunchingWithOptions: method, set the background of your UINavigationBar with ImageA with [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"ImageA.png"] forBarMetrics:UIBarMetricsDefault];

    When the side menu starts to open, you are going to want switch the UINavigationBar so it uses ImageB and create a view which you will add underneath the UIStatusBar. Here is some sample code for doing just that:

    // Add a property for your "temporary status bar" view
    @property (nonatomic, strong) UIView *temporaryStatusBar;
    

    And in the code where the side menu starts to open:

    // Create a temporary status bar overlay
    self.temporaryStatusBar = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] statusBarFrame]];
    self.temporaryStatusBar.backgroundColor = [UIColor yourColor];
    [self.navigationController.view addSubview:self.temporaryStatusBar];
    
    // Update both the current display of the navigationBar and the default appearance values
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"imageB.png"] forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"imageB.png"] forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setNeedsDisplay];
    

    As the side menu animates open, or as the user pans the menu, all you need to do then is adjust the alpha level of the UIStatusBar overlay. When the side menu is fully open, the UINavigationBar should have ImageB as its background image and the UIStatusBar overlay should have an alpha of 0. When the side menu closes, you'll want to replace the UINavigationBar background with ImageA and remove the UIStatusBar overlay.

    Let me know if this works for you!

    0 讨论(0)
提交回复
热议问题