14

这可能吗?

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

4

9 回答 9

21

由于我支持 Colin 的回答,我想给你一个额外的提示来自定义 UINavigationBar 的外观,包括 alpha。

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

这里我给你一些代码片段

  1. 例如,在您的 ..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 中重新创建图像。(AppDelegate.m 中的#import "UIImage+initWithColor.h" 并替换 "nil"):

这是您感兴趣的地方:通过更改颜色的 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]];

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

NavigationBar 的屏幕截图,alpha=0.2 NavigationBar 的屏幕截图,alpha=0.8

于 2013-07-09T07:25:52.047 回答
7

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

let navigationBackgroundView = self.navigationController?.navigationBar.subviews.first
navigationBackgroundView?.alpha = 0.7
于 2016-07-04T11:12:52.700 回答
6

直接来自 Apple Developer 参考:

“您只能对导航栏进行一些直接自定义。具体来说,修改 、 和 属性是可以的barStyletintColortranslucent您绝不能直接更改、、 或属性UIView等级别属性。”frameboundsalphahidden

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

于 2013-07-04T01:09:35.777 回答
3

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
    }
    
于 2015-11-17T00:06:00.383 回答
1

您有几个选项,部分取决于您的UINavigationBar. 主要的是意识到您可能不一定必须为 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的黑色背景- 但您可以设置视图的背景颜色以匹配您的视图以获得您想要的效果:UINavigationControllerUINavigationController

    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. 这很好,只是如果您的子视图锚定在左上角,它们可能会向上移动 44 像素。要解决这个问题,您可以考虑将子视图锚定到视图的底部(使用弹簧或布局约束)。

UIBarStyleDefaultUIBarStyleBlackOpaque选项 CUINavigationBar用另一个视图覆盖,再次使用交叉溶解过渡动画:

        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];

UIBarStyleBlackTranslucent:这个选项是最简单的,因为UINavigationBar它已经是半透明的,并且你的视图已经在它后面了。简单地为 alpha 设置动画:

    [UIView animateWithDuration: 1.0
                     animations: ^{

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

                     }];
于 2013-07-12T20:20:09.993 回答
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];
于 2013-07-06T22:39:58.480 回答
1

也可以尝试在导航栏下方设置一个背景视图,直接修改这个视图。

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
}
于 2017-06-20T11:42:23.440 回答
0

这应该会给你你想要的效果:

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

没有在动画中尝试过,但在我的 viewDidAppear 中有效,希望它有效。

于 2013-07-06T07:04:51.837 回答
0

斯威夫特3

var navAlpha = // Your appropriate calculation   
self.navigationController!.navigationBar.backgroundColor =  UIColor.red.withAlphaComponent(navAlpha)
于 2017-07-24T12:48:53.497 回答