更改导航栏的Alpha值

时间:2013-07-04 00:35:03

标签: ios objective-c uiview uinavigationcontroller uinavigationbar

这可能吗?

我想在视图控制器中更改导航栏的alpha值(在动画中),但是如果我self.navigationController.navigationBar.alpha = 0.0;,导航栏占用的屏幕部分完全消失并留下黑盒子,这不是我想要的(我更喜欢它是self.view背景的颜色。)

9 个答案:

答案 0 :(得分:21)

当我支持Colin的回答时,我想给你一个额外的提示来定制包含alpha的UINavigationBar的外观。

诀窍是为您的NavigationBar使用 UIAppearance 。这使您可以将UIImage分配给NavigationBar的 backgroundImage 。您可以以编程方式生成这些UIImages并用于该UIColors并根据需要设置颜色的alpha属性。我已经在我自己的一个应用程序中完成了这项工作,它按预期工作。

我在这里为您提供了一些代码段

  1. E.g。在你的..AppDelegate.m中添加didFinishLaunchingWithOptions中的这些行:

    //create background images for the navigation bar
    UIImage *gradientImage44 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for portrait orientation
    UIImage *gradientImage32 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for landscape orientation
    
    //customize the appearance of UINavigationBar
    [[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
    [[UINavigationBar appearance] setBarStyle:UIBarStyleDefault];
    
  2. 实现便捷方法以编程方式创建UIImage对象,例如为UIImage创建一个新类别:

    //UIImage+initWithColor.h
    //
    #import <UIKit/UIKit.h>
    
    @interface UIImage (initWithColor)
    
    //programmatically create an UIImage with 1 pixel of a given color
    + (UIImage *)imageWithColor:(UIColor *)color;
    
    //implement additional methods here to create images with gradients etc.
    //[..]
    
    @end
    
    //UIImage+initWithColor.m
    //
    #import "UIImage+initWithColor.h"
    #import <QuartzCore/QuartzCore.h>
    
    @implementation UIImage (initWithColor)
    
    + (UIImage *)imageWithColor:(UIColor *)color
    {
        CGRect rect = CGRectMake(0, 0, 1, 1);
    
        // create a 1 by 1 pixel context 
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
        [color setFill];
        UIRectFill(rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    
  3. 在1.(#import“UIImage + initWithColor.h”在AppDelegate.m中重新创建图像并替换“nil”):

  4. 这是您感兴趣的地方:通过更改颜色的alpha属性,您也会影响NavigationBar的不透明度级别!

                UIImage *gradientImage44 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];
                UIImage *gradientImage32 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];
    

    我创建了一个小型演示项目,并为您添加了两个屏幕截图: 视图本身有一个黄色backgroundColor。 NavigationBar的backgroundImages具有红色。 屏幕截图1显示了一个NavigationBar,其值为alpha = 0.2。 屏幕截图2显示了一个NavigationBar,其值为alpha = 0.8。

    Screenshot for NavigationBar with alpha=0.2 Screenshot for NavigationBar with alpha=0.8

答案 1 :(得分:7)

最直接的方法是修改navigationBar背景视图的alpha组件,此时(iOS9)是第一个navigationBar子视图。但请注意,我们永远不知道在以后的版本中是否会由apple更改子视图层次结构,所以必须小心。

let navigationBackgroundView = self.navigationController?.navigationBar.subviews.first
navigationBackgroundView?.alpha = 0.7

答案 2 :(得分:6)

直接来自Apple Developer参考:

  

“您只能进行少量直接自定义   导航栏。具体来说,可以修改barStyle,   tintColortranslucent属性,但您绝不能直接   更改UIView级别属性,例如framebounds,   直接alphahidden属性。“

但是,您可以设置导航栏的半透明属性。如果你做[self.navigationController.navigationBar setTranslucent:YES]; 应该解决你的问题。您还可以尝试查看是否有任何UIBarStyle枚举。

答案 3 :(得分:2)

MickBraun在Swift中的回答:

  1. 在AppDelegate.swift中,在didFinishLaunchingWithOptions中添加以下行:

    // create background images for the navigation bar
    let gradientImage44 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
    let gradientImage32 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
    
    // customize the appearance of UINavigationBar
    UINavigationBar.appearance().setBackgroundImage(gradientImage44, forBarMetrics: .Default)
    UINavigationBar.appearance().setBackgroundImage(gradientImage32, forBarMetrics: .Compact)
    UINavigationBar.appearance().barStyle = .Default
    
  2. 实现便捷方法以编程方式创建UIImage对象。

    class func imageWithColor(colour: UIColor) -> UIImage {
        let rect = CGRectMake(0, 0, 1, 1)
    
        // Create a 1 by 1 pixel content
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        colour.setFill()
        UIRectFill(rect)
    
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    
        return image
    }
    

答案 4 :(得分:1)

如果你只想以动画的方式摆脱navigationBar,你可以这样做:

[self.navigationController setNavigationBarHidden:YES animated:YES];

如果您想控制动画以及将alpha设置为0.0所需的动画,请继续阅读:

您看到的“黑匣子”来自底层视图或窗口。如果您只是希望您的视图颜色而不是“黑匣子”,请执行:

self.navigationController.view.backgroundColor = self.view.backgroundColor;

[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
    self.navigationController.navigationBar.alpha = 0.0;
} completion:NULL];

如果您希望实际视图位于navigationBar的位置,则需要增加视图的height

[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
    self.navigationController.navigationBar.alpha = 0.0;

    CGFloat navigationBarHeight = self.navigationController.navigationBar.frame.size.height;

    CGRect frame = self.view.frame;
    frame.origin.y -= navigationBarHeight;
    frame.size.height += navigationBarHeight;
    self.view.frame = frame;
} completion:NULL];

答案 5 :(得分:1)

您有一些选项,部分取决于UINavigationBar的barStyle。最重要的是要意识到你可能不一定要为alpha属性设置动画以获得你所描述的效果。

UIBarStyleDefaultUIBarStyleBlackOpaque选项A 是将您的UINavigationBar半透明属性设置为YES,然后为Alpha设置动画:

            navigationBar.translucent = YES; // ideally set this early, in the nib/storyboard, or viewDidLoad

...

            [UIView animateWithDuration: 1.0
                             animations: ^{

                                 // toggle:
                                 navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;

                             }];

在这种情况下,您的视图将定位在导航栏后面,即使其alpha值为1.0。这种情况的缺点是,即使使用1.0 alpha,您也可能会看到UINavigationBar背后的视图背景色。此外,您的所有子视图都需要从顶部向下定位44个点。

UIBarStyleDefaultUIBarStyleBlackOpaque选项B 是在交叉解析过渡动画中隐藏导航栏。这将公开UINavigationBar的超级视图。如果您使用的是UINavigationController,那么UINavigationController视图的黑色背景就是您所看到的 - 但您可以设置UINavigationController视图的背景颜色以使您的视图与得到你想要的效果:

    UINavigationBar* navigationBar = self.navigationController.navigationBar;

    self.navigationController.view.backgroundColor = self.view.backgroundColor;
    [UIView transitionWithView: navigationBar
                      duration: 1.0
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^{
                        // toggle:
                        navigationBar.hidden = !navigationBar.hidden;
                    }
                    completion: nil];

如果UINavigationController因为您隐藏了UINavigationBar UIBarStyleDefault更新了您的视图框架,那么使用此解决方案需要注意的一件事可能是布局问题。这样就可以了,但是如果你的子视图锚定在左上角,你的子视图可能会向上移动44像素。要解决此问题,您可以考虑将子视图锚定到视图的底部(使用弹簧或布局约束)。

UIBarStyleBlackOpaqueUINavigationBar选项C 是用另一个视图掩盖 UINavigationBar* navigationBar = self.navigationController.navigationBar; [UIView transitionWithView: navigationBar duration: 1.0 options: UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowAnimatedContent animations: ^{ // toggle: const int tag = 1111; UIView* navOverlayView = [navigationBar viewWithTag: tag]; if ( navOverlayView == nil ) { navOverlayView = [[UIView alloc] initWithFrame: CGRectInset( navigationBar.bounds, 0, -3 ) ]; navOverlayView.backgroundColor = self.view.backgroundColor; navOverlayView.tag = tag; [navigationBar addSubview: navOverlayView]; } else { [navOverlayView removeFromSuperview]; } } completion: nil]; ,再次使用交叉解析过渡动画:

UINavigationBar

UIBarStyleBlackTranslucent :此选项最简单,因为 [UIView animateWithDuration: 1.0 animations: ^{ // toggle: navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0; }]; 已经是半透明的,您的视图已经落后于它。只需为alpha设置动画:

{{1}}

答案 6 :(得分:0)

这可以让你得到你想要的效果:

self.navigationController.navigationBar.alpha = 0.0;
self.navigationController.navigationBar.frame = CGRectMake(0,0,320,0);

没有在动画中尝试这个,但是在我的viewDidAppear中工作,希望它有效。

答案 7 :(得分:0)

您还可以尝试在导航栏下方设置背景视图,并直接修改此视图。

private lazy var backgroundView: UIView = UIView()

...

private func setupNavigationBarBackground() {
    guard let navigationBar = navigationController?.navigationBar else { return }
    navigationBar.setBackgroundImage(UIImage(), for: .default)
    navigationBar.isTranslucent = true
    view.addSubview(backgroundView)
    backgroundView.alpha = 0
    backgroundView.backgroundColor = .red
    backgroundView.translatesAutoresizingMaskIntoConstraints = false
    backgroundView.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor).isActive = true
    backgroundView.bottomAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
    backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
}

private func changeNavigationBarAlpha(to alpha: CGFloat) {
    backgroundView.alpha = alpha
}

答案 8 :(得分:0)

<强> Swift3

var navAlpha = // Your appropriate calculation   
self.navigationController!.navigationBar.backgroundColor =  UIColor.red.withAlphaComponent(navAlpha)