UINavigationBar 自定义颜色细线边框

UINavigationBar Custom Color Hairline Border

首先,我在发布这个问题之前确实进行了搜索,但如果有答案,它就被埋没在关于如何 删除导航栏的默认底部边框。

我不想删除导航栏的底部边框 ("shadow")。


我正尝试通过使用外观代理的常用方法 "theme" 我的应用程序。 我可以使用如下代码全局更改 UINavigationBar 的大多数视觉属性:

let navigationBarProxy = UINavigationBar.appearance()
navigationBarProxy.isTranslucent = false
navigationBarProxy.barTintColor = myBarBackgroundColor
navigationBarProxy.tintColor = myBarTextColor

关于条形图的 'hairline' 底部边框(或众所周知的 "shadow"),我可以通过什么都不做或指定 nil 来设置默认边框:

navigationBarProxy.shadowImage = nil

...或者我可以指定一个自定义颜色,方法是分配我想要的颜色的实体图像

navigationBarProxy.shadowImage = UIImage.withColor(myBorderColor)

(使用辅助扩展:)

extension UIImage {
    public static func withColor(_ color: UIColor?, size: CGSize = CGSize(width: 1, height: 1)) -> UIImage? {
        let rect = CGRect(origin: CGPoint.zero, size: size)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        let actualColor = color ?? .clear
        context?.setFillColor(actualColor.cgColor)
        context?.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

但是,上面的方法给了我(在视网膜设备上)一个1pt,2px边框,而默认的是浅灰色的实际上是0.5pt, 1px (a.k.a."hairline").

有什么方法可以为 UINavigationBar 实现 0.5 pt (1px)、自定义颜色的底部边框(阴影)?


我想我可以使用运行时生成的背景图像,该图像大部分是纯色的,但底部有一个我选择颜色 "baked in" 的 1px 边框。但这充其量看起来并不优雅,而且我不确定当导航栏高度发生变化时它会如何工作:图像是 sliced,还是简单地拉伸,还是什么?

基于此处找到的所选答案(由于旧而略有改动):

How to change the border color below the navigation bar?

// in viewDidLoad
UIView * navBorder = [[UIView alloc] initWithFrame:CGRectMake(0,
                                                              self.navigationController.navigationBar.frame.size.height, // <-- same height, not - 1
                                                              self.navigationController.navigationBar.frame.size.width,
                                                              1/[UIScreen mainScreen].scale)]; // <-- 5/5S/SE/6 will be 0.5, 6+/X will be 0.33
// custom color here
[navBorder setBackgroundColor:customColor];

[self.navigationController.navigationBar addSubview:navBorder];


以编程方式找到规模的信用:

*注意:
iPhone 6+/X 是 x3,所以 1px 高度就是 0.33pt
iPhone 5/5S/SE/6 是 x2,所以 1px 高度将是 0.5pt
在模拟器中测试,可能需要在实际设备上验证。

在视觉上与具有自定义颜色的默认导航栏相同。

我相信你想去除阴影。这应该对此有所帮助。

[[UINavigationBar appearance] setShadowImage:[UIImage new]];

如果你想要不同颜色的阴影,那么你可以用你想要的颜色创建一个图像并使用它来代替

[UIImage new]

您可以使用类似的方法自己生成图像

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    const CGFloat alpha = CGColorGetAlpha(color.CGColor);
    const BOOL opaque = alpha == 1;
    UIGraphicsBeginImageContextWithOptions(rect.size, opaque, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}