ios 更改导航栏的 alpha 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17460209/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Change the alpha value of the navigation bar
提问by Doug Smith
Is this possible?
这可能吗?
I want to change the alpha value of the navigation bar in my view controller (in an animation), but if I do self.navigationController.navigationBar.alpha = 0.0;
, the portion of the screen the navigationBar took up totally disappears and leaves a black box, which is not what I'd like (I'd prefer it to be the color of self.view
's background).
我想在我的视图控制器中更改导航栏的 alpha 值(在动画中),但是如果我这样做self.navigationController.navigationBar.alpha = 0.0;
,导航栏占据的屏幕部分将完全消失并留下一个黑框,这不是我想要的喜欢(我更喜欢它是self.view
背景的颜色)。
回答by Computerspezl
As I support Colin's answer, I want to give you an additional hint to customize the appearance of an UINavigationBar including the alpha.
因为我支持 Colin 的回答,所以我想给你一个额外的提示来自定义 UINavigationBar 的外观,包括 alpha。
The trick is to use UIAppearancefor your NavigationBar. This enables you to assign an UIImage to your NavigationBar's backgroundImage. You can generate these UIImages programmatically and use for that UIColors and set the colors' alpha propertiesas you want. I've done this in one of my own applications and it works as expected.
诀窍是为您的 NavigationBar使用UIAppearance。这使您可以将 UIImage 分配给 NavigationBar 的backgroundImage。您可以以编程方式生成这些 UIImages 并用于该 UIColors 并根据需要设置颜色的 alpha 属性。我已经在我自己的应用程序之一中完成了此操作,并且它按预期工作。
Here I give you some code snippets:
在这里,我给你一些代码片段:
E.g. in your ..AppDelegate.m add these lines in 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];
Implement convenience methods to programmatically creates UIImage objects, e.g. create a new category for 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; }
Re-work your image creation in 1. (#import "UIImage+initWithColor.h" in AppDelegate.m and replace the "nil"s):
例如,在您的 ..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];
实现以编程方式创建 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; }
在 1 中重新创建图像。(#import "UIImage+initWithColor.h" in AppDelegate.m 并替换 "nil"s):
This is your spot of interest: by changing your colors' alpha property you are influencing the opacity level of you NavigationBar as well!
这是您感兴趣的地方:通过更改颜色的 alpha 属性,您也会影响导航栏的不透明度级别!
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]];
I created a small demo projectand add you two screenshots: the view itself has a yellow backgroundColor. The backgroundImages of the NavigationBar have a red color. Screenshot 1 shows a NavigationBar with a value for alpha = 0.2. Screenshot 2 shows a NavigationBar with a value for alpha = 0.8.
我创建了一个小型演示项目并添加了两个屏幕截图:视图本身具有黄色背景颜色。NavigationBar 的 backgroundImages 具有红色。屏幕截图 1 显示了一个值为 alpha = 0.2 的 NavigationBar。屏幕截图 2 显示了一个值为 alpha = 0.8 的 NavigationBar。
回答by ambientlight
The most straightforward way of doing this is modifying the alpha component of navigationBar background view, which at this time (iOS9) is a first navigationBar subview. Note however that we never know if the subview hierarchy will be changed by apple in later releases, so gotta be careful.
最直接的做法是修改navigationBar背景视图的alpha组件,此时(iOS9)是第一个navigationBar子视图。但是请注意,我们永远不知道 Apple 在以后的版本中是否会更改子视图层次结构,因此必须小心。
let navigationBackgroundView = self.navigationController?.navigationBar.subviews.first
navigationBackgroundView?.alpha = 0.7
回答by Colin
Directly from the Apple Developer reference:
直接来自 Apple Developer 参考:
"there are only a handful of direct customizations you can make to the navigation bar. Specifically, it is alright to modify the
barStyle
,tintColor
, andtranslucent
properties, but you must never directly changeUIView
-level properties such as theframe
,bounds
,alpha
, orhidden
properties directly."
“只有直接定制了一把,你可以对导航栏。具体来说,它是正常的修改
barStyle
,tintColor
和translucent
属性,但你绝不能直接改变UIView
-电平特性,如frame
,bounds
,alpha
,或hidden
直接性。”
You can however set the translucence property of the navigation bar. If you do [self.navigationController.navigationBar setTranslucent:YES];
should solve your problem. You can also try seeing if any of the UIBarStyle
enums are something you want.
但是,您可以设置导航栏的半透明属性。如果你这样做[self.navigationController.navigationBar setTranslucent:YES];
应该可以解决你的问题。您还可以尝试查看是否有任何UIBarStyle
枚举是您想要的。
回答by Allanah Douglas
MickBraun's answer in Swift:
MickBraun 在 Swift 中的回答:
In AppDelegate.swift add these lines in 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
Implement convenience methods to programmatically create UIImage objects.
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 }
在 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
实现以编程方式创建 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 }
回答by Danilo
If you just want to get rid of the navigationBar
in an animated way you could do:
如果您只想以navigationBar
动画方式摆脱 ,您可以这样做:
[self.navigationController setNavigationBarHidden:YES animated:YES];
If you want to control the animation and its necessary to set the alpha
to 0.0
, read on:
如果您想控制动画并且需要将其设置alpha
为0.0
,请继续阅读:
The "black box" you are seeing is from the underlying view or window. If you just want your views color instead of the "black box" do:
您看到的“黑匣子”来自底层视图或窗口。如果您只想要视图颜色而不是“黑匣子”,请执行以下操作:
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];
If you want your actual view to be where the navigationBar
was, you need to increase the height
of your view:
如果您希望您的实际视图位于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];
回答by TomSwift
You have a few options depending, in part, upon the barStyle of your UINavigationBar
. The main thing is realizing that you likely don't necessarily have to animate the alpha property to get the effect you're describing.
您有几个选项,部分取决于您的UINavigationBar
. 主要的事情是意识到您可能不一定要为 alpha 属性设置动画来获得您所描述的效果。
UIBarStyleDefault
or UIBarStyleBlackOpaque
Option Ais to set your UINavigationBar translucent property to YES, then animate the alpha:
UIBarStyleDefault
或UIBarStyleBlackOpaque
选项 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;
}];
In this scenario your view will be positioned behind your navbar, even when its alpha is 1.0. The downside to this scenario is that even with a 1.0 alpha you might see a tinge of your view's background color behind the UINavigationBar. Also, all of your subviews will need to be positioned 44 points down from the top.
在这种情况下,您的视图将位于导航栏后面,即使其 alpha 为 1.0。这种情况的缺点是,即使使用 1.0 alpha,您也可能会在 UINavigationBar 后面看到视图的背景颜色。此外,您的所有子视图都需要位于从顶部向下 44 点的位置。
UIBarStyleDefault
or UIBarStyleBlackOpaque
Option Bis to hide the navbar in a cross-disolve transition animation. This will expose the superview of the UINavigationBar
. If you're using a UINavigationController
then the black background of the UINavigationController
view is what you'll see - but you can set the background color of the UINavigationController
view to match your view to get the effect that you want:
UIBarStyleDefault
或UIBarStyleBlackOpaque
选项 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];
One thing to watch out for with this solution might be a layout issue if the UINavigationController
updates your view frame because you hid the UINavigationBar
. This would be fine except that your subviews might shift up 44 pixels if they're anchored to the top left. To work around this you might consider anchoring your subviews to the bottom of your view instead (either with springs or with layout constraints).
如果UINavigationController
因为您隐藏了UINavigationBar
. 这很好,只是如果您的子视图锚定在左上角,它们可能会向上移动 44 像素。要解决此问题,您可以考虑将子视图锚定到视图底部(使用弹簧或布局约束)。
UIBarStyleDefault
or UIBarStyleBlackOpaque
Option Cis to cover up the UINavigationBar
with another view, again using a cross-disolve transition animation:
UIBarStyleDefault
或UIBarStyleBlackOpaque
选项 C是UINavigationBar
用另一个视图覆盖,再次使用交叉溶解过渡动画:
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: This option is the easiest, as the UINavigationBar
is already translucent, and your view is already behind it. Simply animate the alpha:
UIBarStyleBlackTranslucent:这个选项是最简单的,因为UINavigationBar
已经是半透明的,你的视图已经在它后面了。简单地为 alpha 设置动画:
[UIView animateWithDuration: 1.0
animations: ^{
// toggle:
navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;
}];
回答by JustAnotherCoder
This should get you the effect you desire:
这应该会让你得到你想要的效果:
self.navigationController.navigationBar.alpha = 0.0;
self.navigationController.navigationBar.frame = CGRectMake(0,0,320,0);
Did not try this in an animation, works in my viewDidAppear though, hope it works.
没有在动画中尝试这个,虽然在我的 viewDidAppear 中有效,但希望它有效。
回答by GaétanZ
You can also try to set a background view underneath the navigation bar and modify this view directly.
也可以尝试在导航栏下方设置一个背景视图,直接修改这个视图。
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
}
回答by Deven
Swift3
斯威夫特3
var navAlpha = // Your appropriate calculation
self.navigationController!.navigationBar.backgroundColor = UIColor.red.withAlphaComponent(navAlpha)