【问题标题】:UIStatusBar as in Facebook new iOS7 applicationUIStatusBar 在 Facebook 新的 iOS7 应用程序中
【发布时间】:2013-10-02 12:56:15
【问题描述】:

我有一个带有侧边栏菜单的应用程序,有点像 Facebook 侧边栏菜单。我正在使用这个名为SWRevealViewController 的类,它运行良好。现在自从 iOS7 出来了,我就是不知道如何调整我的状态和导航栏,就像在 Facebook 应用程序中一样。

如您所见,在 Facebook 应用程序中,当用户滑动屏幕并打开菜单时,状态栏会从导航栏的蓝色变为黑色并带有淡入淡出动画。在我的应用程序中,用户滑动屏幕以打开菜单,蓝色的状态栏(由于该视图 NavigationBar 是蓝色的)不会消失并将颜色变为黑色。

另外,我遇​​到的另一个问题是,我无法将 StatusBar 文本颜色更改为白色。我已经尝试了一切,互联网上的每一段代码,阅读了所有苹果的文档,但仍然无法改变颜色。

我也用过这段代码:

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationFade;
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}

- (BOOL)prefersStatusBarHidden
{
    return NO;
}

提前致谢。

================================================ ==========================

更新:在@yoeriboven 的回答中,这个问题的解决方案是在SWRevealViewController 的顶部放置两个视图,黑色和蓝色,然后只为这两个设置动画,这很棒解决方案,效果很好。

所以,在创建revealController 时,我创建了2 个空白UIView 并添加了它们,一个蓝色和一个黑色。其中一个,黑色的,我暂时隐藏了。

self.revealController = [[SWRevealViewController alloc] initWithRearViewController:nil frontViewController:self.frontViewController];
self.revealController.delegate = self;

self.appDelegate.window.rootViewController = self.revealController;

self.statusBarBlack = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.appDelegate.window.frame.size.width, 20)];
[self.statusBarBlack setBackgroundColor:[UIColor blackColor]];

self.statusBarBlue = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.appDelegate.window.frame.size.width, 20)];
[self.statusBarBlue setBackgroundColor:[UIColor blueColor]];

[self.appDelegate.window.rootViewController.view addSubview:self.statusBarBlack];
[self.appDelegate.window.rootViewController.view addSubview:self.statusBarBlue];

现在,如果您使用的是SWRevealViewController,您可以使用下一个代码,如果没有,请自行构建它,在SWRevealViewController.m 中只需#import "AppDelegate.h",然后用这个替换touchesMoved 方法:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];

    if (self.state == UIGestureRecognizerStateFailed)
        return;

    //  Change color of status bar by the location of your swipe
    AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    UITouch *currentTouch = [touches anyObject];
    CGPoint currentTouchLocationOnWindow = [currentTouch locationInView:appDelegate.window];
    appDelegate.splashScreen.blueStatusBar.alpha = currentTouchLocationOnWindow.x / appDelegate.window.frame.size.width;

    if ( _dragging )
        return;

    const int kDirectionPanThreshold = 5;

    UITouch *touch = [touches anyObject];
    CGPoint nowPoint = [touch locationInView:self.view];

    CGFloat moveX = nowPoint.x - _init.x;
    CGFloat moveY = nowPoint.y - _init.y;

    if (abs(moveX) > kDirectionPanThreshold)
    {
        if (_direction == SWDirectionPanGestureRecognizerHorizontal)
            _dragging = YES;
        else
            self.state = UIGestureRecognizerStateFailed;
    }
    else if (abs(moveY) > kDirectionPanThreshold)
    {
        if (_direction == SWDirectionPanGestureRecognizerVertical)
            _dragging = YES ;
        else
            self.state = UIGestureRecognizerStateFailed;
    }
}

现在再往下一点,搜索rightRevealToggleAnimated这个方法,把她换成这个:

- (void)rightRevealToggleAnimated:(BOOL)animated
{
    FrontViewPosition toogledFrontViewPosition = FrontViewPositionLeft;
    if (_frontViewPosition >= FrontViewPositionLeft) {
        toogledFrontViewPosition = FrontViewPositionLeftSide;
        [UIView animateWithDuration:0.3 animations:^{
            //  Change color of status bar
            AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
            appDelegate.splashScreen.blueStatusBar.alpha = 0.0;
        }];
    } else {
        [UIView animateWithDuration:0.3 animations:^{
            //  Change color of status bar
            AppDelegate *appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
            appDelegate.splashScreen.blueStatusBar.alpha = 1.0;
        }];
    }

    [self setFrontViewPosition:toogledFrontViewPosition animated:animated];
}

这应该可以解决问题,享受吧!

【问题讨论】:

  • 更改状态栏样式时,不要忘记在呈现的视图控制器上调用setNeedsStatusBarAppearanceUpdate
  • 我在 viewDidLoad 方法上调用它,还是一样。
  • 我不确定这是不是正确的地方。在 viewDidAppear 中尝试。
  • 放在 viewDidAppear 和 viewWillAppear 中,还是一样的结果。

标签: ios objective-c ios7 uinavigationbar uistatusbar


【解决方案1】:

在 iOS 7 中,您的视图控制器的视图是全屏的。因此,您可以在视图的顶部 22 像素(状态栏高度)处将两个视图相互叠加。底部的黑色和顶部的颜色与您的导航栏相同。当滑动到SWRevealViewController 时,您可以使用UIScrollView 委托方法之一计算它的百分比,并将该值应用到带有导航栏颜色的子视图的不透明度。

【讨论】:

  • 这是一个很好的解决方案,我也为那些需要它的人更新了我的答案。谢谢大佬!
  • 对您有帮助。如果您检查我的答案是否正确,那就太好了。祝你的项目好运。
【解决方案2】:

我还有另一种方法也很有效。

首先在 SWRevealView 类的 SWRevealViewController.h 中创建一个名为 underStatusBarViewView @property 以放置在状态栏位置。

然后在- (id)initWithFrame:(CGRect)frame controller:(SWRevealViewController*)controller 方法中,我实例化@property,将其颜色设置为黑色,并将其alpha 设置为0。

- (id)initWithFrame:(CGRect)frame controller:(SWRevealViewController*)controller
{
    self = [super initWithFrame:frame];
    if ( self )
    {
        _c = controller;
        CGRect bounds = self.bounds;

        _frontView = [[UIView alloc] initWithFrame:bounds];
        _frontView.autoresizingMask =   UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

        [self addSubview:_frontView];

        CALayer *frontViewLayer = _frontView.layer;
        frontViewLayer.masksToBounds = NO;
        frontViewLayer.shadowColor = [UIColor blackColor].CGColor;

        /* Here starts my under status bar implementation */
        CGRect statusFrame = [[UIApplication sharedApplication]statusBarFrame];
        _underStatusBarView = [[UIView alloc]initWithFrame:statusFrame];
        [_underStatusBarView setBackgroundColor:[UIColor blackColor]];
        [_underStatusBarView setAlpha:0.0];
        [self addSubview:_underStatusBarView];
        /* here it ends */

        //frontViewLayer.shadowOpacity = 1.0f;
        frontViewLayer.shadowOpacity = _c.frontViewShadowOpacity;
        frontViewLayer.shadowOffset = _c.frontViewShadowOffset;
        frontViewLayer.shadowRadius = _c.frontViewShadowRadius;
    }

    return self;
}

然后我在负责布局后视图- (void)_layoutRearViewsForLocation:(CGFloat)xLocation的私有方法中添加了一行代码,以根据前视图位置更改_underStatusBarView alpha。

- (void)_layoutRearViewsForLocation:(CGFloat)xLocation
{
    CGRect bounds = self.bounds;

    CGFloat rearRevealWidth = _c.rearViewRevealWidth;
    if ( rearRevealWidth < 0) rearRevealWidth = bounds.size.width + _c.rearViewRevealWidth;

    CGFloat rearXLocation = scaledValue(xLocation, -_c.rearViewRevealDisplacement, 0, 0, rearRevealWidth);

    CGFloat rearWidth = rearRevealWidth + _c.rearViewRevealOverdraw;
    _rearView.frame = CGRectMake(rearXLocation, 0.0, rearWidth, bounds.size.height);

    CGFloat rightRevealWidth = _c.rightViewRevealWidth;
    if ( rightRevealWidth < 0) rightRevealWidth = bounds.size.width + _c.rightViewRevealWidth;

    CGFloat rightXLocation = scaledValue(xLocation, 0, _c.rightViewRevealDisplacement, -rightRevealWidth, 0);

    CGFloat rightWidth = rightRevealWidth + _c.rightViewRevealOverdraw;
    _rightView.frame = CGRectMake(bounds.size.width-rightWidth+rightXLocation, 0.0f, rightWidth, bounds.size.height);

    /*this line changes the under status bar view alpha*/
   _underStatusBarView.alpha = xLocation/rearRevealWidth;
}

您如何使用 rightRevealView 您应该将 rearRevealWidht 更改为 rightRevealWidth 以防止将来出现兼容性问题。

【讨论】:

  • 这在纵向上工作得很好,但是当我在 iPad 上转到横向时,当显示后视图时,黑色状态栏不会一直穿过屏幕顶部。我该如何解决这个问题?
【解决方案3】:

我真的很喜欢你的方法。我对您的代码进行了几次更新,并希望将其提交给项目。如果您对我这样做有任何问题,请告诉我。

【讨论】:

  • 此类回复请使用 cmets,请勿使用答案
  • 我试过了。不幸的是,要评论其他人的答案,您的声望必须至少为 50。
  • 请尽可能使用其他渠道,最好保留很少回复的问题,以免混淆谷歌员工或寻找答案的人,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多