如何为 UINavigationBar 设置不透明的 1px 高阴影图像?
Posted
技术标签:
【中文标题】如何为 UINavigationBar 设置不透明的 1px 高阴影图像?【英文标题】:How do a set an opaque 1px high shadow image for a UINavigationBar? 【发布时间】:2014-12-02 20:08:48 【问题描述】:在我的应用程序委托的 didFinishLaunchingWithOptions 函数中,我尝试自定义导航栏的外观。
[UINavigationBar appearance].translucent = NO;
[[UINavigationBar appearance]
setBackgroundImage:[UIImage
imageWithColor:[UIColor whiteColor]
size:CGSizeMake(1.0f, 1.0f)
]
forBarMetrics:UIBarMetricsDefault
];
[UINavigationBar appearance].shadowImage = [UIImage
imageWithColor:[UIColor redColor]
size:CGSizeMake(0.5f, 0.5f)
];
我希望有一个 1 像素高的不透明红色阴影。相反,我得到了一个 2px 高的半透明红色阴影。怎样才能让它完全按照我想要的样子出现?我已经完成了与 UITabBar 类似的外观设置。另一方面,它表现得很好。
创建动态图像的类别函数定义如下:
+ (UIImage*)imageWithColor:(UIColor *)color size:(CGSize)size
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
【问题讨论】:
您是否考虑过为 CALayer 添加阴影?见***.com/questions/805872/… @cmyr[UINavigationBar appearance].layer.borderWidth = 0.5f; [UINavigationBar appearance].layer.borderColor = [UIColor redColor].CGColor;
在导航栏下不显示任何内容。
您是否将图层的 clipsToBounds 设置为 NO?
【参考方案1】:
您需要创建一个可识别视网膜的图形上下文:
let pixelScale = UIGraphicsBeginImageContextWithOptions(fillRect.size, false, UIScreen.main.scale)
之后,您的阴影图像将变为 1 个物理像素高。
这里是完整的代码:
extension UIImage
static func imageWithColor(color: UIColor) -> UIImage
let pixelScale = UIScreen.main.scale
let pixelSize = 1 / pixelScale
let fillSize = CGSize(width: pixelSize, height: pixelSize)
let fillRect = CGRect(origin: CGPoint.zero, size: fillSize)
UIGraphicsBeginImageContextWithOptions(fillRect.size, false, pixelScale)
let graphicsContext = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(graphicsContext, color.CGColor)
CGContextFillRect(graphicsContext, fillRect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
在 GitHub 上:
https://github.com/salutis/swift-image-with-color
【讨论】:
我建议将填充大小设为 1, pixelSize 而不是 pixelSize, pixelSize,否则会产生水平渐变效果,并且在我的情况下,线条在右点处变得透明。 【参考方案2】:呃……这是你想要的吗?
在我的视图控制器中,我只是添加了一个高度为 1 像素且偏移量为 44 像素的 UIView:
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
[self setupNavBar];
-(void)setupNavBar
self.navigationItem.title = @"Contacts";
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIView *bar = [[UIView alloc] initWithFrame:CGRectMake(0, 44, applicationFrame.size.width, 1.0)];
bar.backgroundColor = [UIColor redColor];
[self.navigationController.navigationBar addSubview:bar];
您可以将颜色更改为您想要的任何颜色。
【讨论】:
恕我直言,我认为将子视图添加到导航栏并不是最佳解决方案。这似乎很容易出错(例如,当多个视图控制器尝试添加视图时,或者 - 特别是 - 当导航栏的视图层次结构可能会随着 ios 的更新版本而改变时)。我认为使用公开可用的功能、自定义背景图像和 UIAppearance 设置会更安全。以上是关于如何为 UINavigationBar 设置不透明的 1px 高阴影图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 DropShadowEffect 的不透明度设置动画?
使用静态 UITableView 时将透明背景设置为 UINavigationBar 会导致过渡效果不佳