如何创建UINavigationBar投影

时间:2022-08-22 21:25:23

Would like to know create drop shadow for UINavigationbar. I tried to create custom navigation bar background with drop shadow, but the drop shadow cover the background view.

想知道UINavigationbar的创建投影。我尝试用投影创建自定义导航条背景,但是投影覆盖了背景视图。

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
   UIImage *image = [[UIImage imageNamed:@"titleBar.png"] retain];;
   [image drawInRect:rect];
   [image release];
}

- (CGSize)sizeThatFits:(CGSize)size {
   CGSize newSize = CGSizeMake(320,50);
   return newSize;
}
@end

I also tried on following solution: http://www.travisboudreaux.com/adding-a-drop-shadow-to-a-uinavigationbar: 

@interface UINavigationBar (dropshadow)

-(void) applyDefaultStyle;

@end

@implementation UINavigationBar (dropshadow)

-(void)willMoveToWindow:(UIWindow *)newWindow{
   [self applyDefaultStyle];
}

- (void)applyDefaultStyle {
  // add the drop shadow
  self.layer.shadowColor = [[UIColor blackColor] CGColor];
  self.layer.shadowOffset = CGSizeMake(0.0, 3.0);
  self.layer.shadowOpacity = 0.25;
}
@end

It shows drop shadow for my navigationbar button, but no the navigation bar itself.

它显示了导航栏按钮的投影,但没有导航栏本身。

Final Solution: Here's how I create drop shadow for UINavigationBar. Big thanks for MusiGenesis for pointing out the missing link of my code:

最后的解决方案:以下是我如何为UINavigationBar创建投影。非常感谢音乐起源指出我的代码丢失的链接:

#import <QuartzCore/QuartzCore.h>

@interface UINavigationBar (CustomImage)

-(void) applyDefaultStyle;

@end

//Override For Custom Navigation Bar
@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"titleBar.png"];
    [image drawInRect:CGRectMake(0, 0, 320, 44)];   
}

-(void)willMoveToWindow:(UIWindow *)newWindow{
    [super willMoveToWindow:newWindow];
    [self applyDefaultStyle];
}

- (void)applyDefaultStyle {
    // add the drop shadow
    self.layer.shadowColor = [[UIColor blackColor] CGColor];
    self.layer.shadowOffset = CGSizeMake(0.0, 3);
    self.layer.shadowOpacity = 0.25;
    self.layer.masksToBounds = NO;
    self.layer.shouldRasterize = YES;
}

@end

** Remember to import quartzcore or it will throw error.

记住导入quartzcore,否则会出现错误。

4 个解决方案

#1


29  

In applyDefaultStyle, try adding this line:

在applyDefaultStyle中,尝试添加以下内容:

self.layer.masksToBounds = NO;

The default value for this property is YES, which means that even though the shadow is rendered, it won't be rendered outside the bounds of the view, which means effectively that you don't see it at all.

这个属性的默认值是YES,这意味着即使影子被呈现,它也不会被显示在视图的边界之外,这意味着您实际上根本看不到它。

If you're animating this view in any way, you should also add this line:

如果你正在以任何方式动画这个视图,你也应该加上这一行:

self.layer.shouldRasterize = YES;

... unless you want the animation to be slow and jerky.

…除非你想让动画变得缓慢而粗糙。

#2


44  

If you apply a drop shadow to a UINavigationBar, the shadow is clipped at below the corners:

如果你在UINavigationBar上添加一个投影,那么阴影就会被裁剪到下面的角落:

如何创建UINavigationBar投影

This is just how shadows behave on rectangles. I usually create a path for the shadow that's a bit wider than the actual nav bar, which creates an effect that is more like what you'd generally expect:

这就是阴影在矩形上的表现。我通常会为阴影创建一条比实际的导航条宽一点的路径,这样会产生一种效果,就像你通常预期的那样:

@implementation UINavigationBar (DropShadow)

-(void)willMoveToWindow:(UIWindow *)newWindow {
    [super willMoveToWindow:newWindow];
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOpacity = 1;
    self.layer.shadowOffset = CGSizeMake(0,4);
    CGRect shadowPath = CGRectMake(self.layer.bounds.origin.x - 10, self.layer.bounds.size.height - 6, self.layer.bounds.size.width + 20, 5);
    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowPath].CGPath;
    self.layer.shouldRasterize = YES;
}

如何创建UINavigationBar投影

#3


9  

Since iOS 6.0, UINavigationBar has a property shadowImage:

自ios6.0以来,UINavigationBar有一个属性shadowImage:

@property(nonatomic,retain) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;

which of course greatly simplifies this very common task :D

这当然大大简化了这个很常见的任务D

#4


-1  

I stick the shadow drawing code into a function to keep loadView clean. You could pass in the object you want to draw the shadow on if you wanted all your shadows consistent.

我将阴影绘制代码插入到一个函数中,以保持loadView的整洁。如果你想要所有的阴影一致,你可以通过你想要画阴影的物体。

- (void)loadView
{
    self.view = [[UIView alloc] init];
    self.view.backgroundColor = [UIColor whiteColor];

    [self drawShadow];
}


- (void)drawShadow
{
    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
    self.navigationController.navigationBar.layer.shadowOpacity = 0.3;
    self.navigationController.navigationBar.layer.shadowOffset = CGSizeMake(0, 0);
    self.navigationController.navigationBar.layer.shadowRadius = 15;
    self.navigationController.navigationBar.layer.masksToBounds = NO;
}

#1


29  

In applyDefaultStyle, try adding this line:

在applyDefaultStyle中,尝试添加以下内容:

self.layer.masksToBounds = NO;

The default value for this property is YES, which means that even though the shadow is rendered, it won't be rendered outside the bounds of the view, which means effectively that you don't see it at all.

这个属性的默认值是YES,这意味着即使影子被呈现,它也不会被显示在视图的边界之外,这意味着您实际上根本看不到它。

If you're animating this view in any way, you should also add this line:

如果你正在以任何方式动画这个视图,你也应该加上这一行:

self.layer.shouldRasterize = YES;

... unless you want the animation to be slow and jerky.

…除非你想让动画变得缓慢而粗糙。

#2


44  

If you apply a drop shadow to a UINavigationBar, the shadow is clipped at below the corners:

如果你在UINavigationBar上添加一个投影,那么阴影就会被裁剪到下面的角落:

如何创建UINavigationBar投影

This is just how shadows behave on rectangles. I usually create a path for the shadow that's a bit wider than the actual nav bar, which creates an effect that is more like what you'd generally expect:

这就是阴影在矩形上的表现。我通常会为阴影创建一条比实际的导航条宽一点的路径,这样会产生一种效果,就像你通常预期的那样:

@implementation UINavigationBar (DropShadow)

-(void)willMoveToWindow:(UIWindow *)newWindow {
    [super willMoveToWindow:newWindow];
    self.layer.shadowColor = [UIColor blackColor].CGColor;
    self.layer.shadowOpacity = 1;
    self.layer.shadowOffset = CGSizeMake(0,4);
    CGRect shadowPath = CGRectMake(self.layer.bounds.origin.x - 10, self.layer.bounds.size.height - 6, self.layer.bounds.size.width + 20, 5);
    self.layer.shadowPath = [UIBezierPath bezierPathWithRect:shadowPath].CGPath;
    self.layer.shouldRasterize = YES;
}

如何创建UINavigationBar投影

#3


9  

Since iOS 6.0, UINavigationBar has a property shadowImage:

自ios6.0以来,UINavigationBar有一个属性shadowImage:

@property(nonatomic,retain) UIImage *shadowImage NS_AVAILABLE_IOS(6_0) UI_APPEARANCE_SELECTOR;

which of course greatly simplifies this very common task :D

这当然大大简化了这个很常见的任务D

#4


-1  

I stick the shadow drawing code into a function to keep loadView clean. You could pass in the object you want to draw the shadow on if you wanted all your shadows consistent.

我将阴影绘制代码插入到一个函数中,以保持loadView的整洁。如果你想要所有的阴影一致,你可以通过你想要画阴影的物体。

- (void)loadView
{
    self.view = [[UIView alloc] init];
    self.view.backgroundColor = [UIColor whiteColor];

    [self drawShadow];
}


- (void)drawShadow
{
    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
    self.navigationController.navigationBar.layer.shadowOpacity = 0.3;
    self.navigationController.navigationBar.layer.shadowOffset = CGSizeMake(0, 0);
    self.navigationController.navigationBar.layer.shadowRadius = 15;
    self.navigationController.navigationBar.layer.masksToBounds = NO;
}