iOS7 - 更改UINavigationBar边框颜色

29

在iOS7中,是否可以更改UINavigationBar的灰色下边框颜色?

我已经尝试删除边框,但这没有起作用:

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];

谢谢!


这将有所帮助: https://dev59.com/gGIk5IYBdhLWcg3wfOOe - Niraj
15个回答

63

你正在移除阴影但是没有移除边框,你需要执行以下操作:

[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];

使用宽度为2个像素的线条图片来更改边框:

[[UINavigationBar appearance] setShadowImage:[UIImage imageNamed:@"2pxWidthLineImage"]]; 

我该如何添加边框?(更改颜色) - MappleDev
该方法可以去除导航栏的半透明效果。 - shikhar.ja
2
“setShadowImage”似乎已经不存在了。 - TIMEX

61

这是一个可以通过高度来改变底部颜色的类别:

[self.navigationController.navigationBar setBottomBorderColor:[UIColor redColor] height:1];

enter image description here

Objective C:

UINavigationBar+Helper.h

#import <UIKit/UIKit.h>

@interface UINavigationBar (Helper)
- (void)setBottomBorderColor:(UIColor *)color height:(CGFloat)height;
@end

UINavigationBar+Helper.m

#import "UINavigationBar+Helper.h"

@implementation UINavigationBar (Helper)

- (void)setBottomBorderColor:(UIColor *)color height:(CGFloat)height {
    CGRect bottomBorderRect = CGRectMake(0, CGRectGetHeight(self.frame), CGRectGetWidth(self.frame), height);
    UIView *bottomBorder = [[UIView alloc] initWithFrame:bottomBorderRect];
    [bottomBorder setBackgroundColor:color];
    [self addSubview:bottomBorder];
}
@end

Swift:

extension UINavigationBar {

    func setBottomBorderColor(color: UIColor, height: CGFloat) {
        let bottomBorderRect = CGRect(x: 0, y: frame.height, width: frame.width, height: height)
        let bottomBorderView = UIView(frame: bottomBorderRect)
        bottomBorderView.backgroundColor = color
        addSubview(bottomBorderView)
    }
}

非常棒的答案。现在我的用户界面看起来好多了 :) - Septronic
我该如何用Swift编写这个? - TIMEX
2
@Vahid 我认为你应该在旋转完成后调用这个方法,它会重新绘制“subViews”,或者简单地重新加载“subViews”。 - iBug
不必使用CGRect来调整边框视图的大小,您可以添加约束条件,这些约束条件将随着旋转和特征更改而调整大小。 - g0ld2k
1
需要在边框视图上设置自动调整大小掩码。 - Pavel Alexeev

9
这里还有另一种方法:
CALayer *border = [CALayer layer];
border.borderColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"border"]].CGColor;
border.borderWidth = 1;
CALayer *layer = self.navigationController.navigationBar.layer;
border.frame = CGRectMake(0, layer.bounds.size.height, layer.bounds.size.width, 1);
[layer addSublayer:border];

7
我找到的唯一更改颜色的方法是:
override func viewDidLoad() {
    super.viewDidLoad()

    if let navigationController = self.navigationController {
        let navigationBar = navigationController.navigationBar
        let navigationSeparator = UIView(frame: CGRectMake(0, navigationBar.frame.size.height - 1, navigationBar.frame.size.width, 0.5))
        navigationSeparator.backgroundColor = UIColor.redColor() // Here your custom color
        navigationSeparator.opaque = true
        self.navigationController?.navigationBar.addSubview(navigationSeparator)
    }

}

太棒了。运行得非常顺畅。 - Katherine Jenkins

5
我用自动布局解决了这个问题。该解决方案适用于不同的屏幕尺寸和方向更改。
extension UINavigationBar {

    @IBInspectable var bottomBorderColor: UIColor {
        get {
            return self.bottomBorderColor;
        }
        set {
            let bottomBorderRect = CGRect.zero;
            let bottomBorderView = UIView(frame: bottomBorderRect);
            bottomBorderView.backgroundColor = newValue;
            addSubview(bottomBorderView);

            bottomBorderView.translatesAutoresizingMaskIntoConstraints = false;

            self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: 0));
            self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 0));
            self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0));
            self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute,multiplier: 1, constant: 1));
        }

    }

}

非常好用,而且可以在Storyboard中进行检查,这很不错!谢谢! - agrippa

5

我基于其他答案编写了一个扩展,以便更轻松地在Swift中使用:

extension UINavigationBar {

    func setBottomBorderColor(color: UIColor) {

        let navigationSeparator = UIView(frame: CGRectMake(0, self.frame.size.height - 0.5, self.frame.size.width, 0.5))
        navigationSeparator.backgroundColor = color
        navigationSeparator.opaque = true
        navigationSeparator.tag = 123
        if let oldView = self.viewWithTag(123) {
            oldView.removeFromSuperview()
        }
        self.addSubview(navigationSeparator)

    }
}

您可以在上下文中调用该方法来使用此扩展:
self.navigationController?.navigationBar.setBottomBorderColor(UIColor.whiteColor())

我发现这非常有用,因为我必须处理那个有色边框问题。


4

根据@sash的回答,我使用Autolayout在Swift中制作了一个扩展,详细解释请看这里

实际上,其他解决方案有以下缺点:

  • 如果使用UIImage解决方案,则无法添加阴影
  • 添加的子视图在视图旋转时不会调整大小
extension UINavigationBar {
func setBottomBorderColor(color: UIColor, height: CGFloat) -> UIView {
let bottomBorderView = UIView(frame: CGRectZero) bottomBorderView.translatesAutoresizingMaskIntoConstraints = false bottomBorderView.backgroundColor = color self.addSubview(bottomBorderView)
let views = ["border": bottomBorderView] self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[border]|", options: [], metrics: nil, views: views)) self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height)) self.addConstraint(NSLayoutConstraint(item: bottomBorderView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: height))
return bottomBorderView } }

这样您仍然可以添加投影(如果需要),而且它可以很好地处理旋转!


这很好,谢谢。我认为你不需要返回一个 UIView。它可以在没有返回值的情况下工作。 - Clifton Labrum

2

如果你和我一样喜欢简单而且有创意的解决方案,可以创建一个视图来覆盖默认的边框:

UIView *navBarLineView = [[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.navigationController.navigationBar.frame),
                                                                  CGRectGetWidth(self.navigationController.navigationBar.frame), 1)];
navBarLineView.backgroundColor = [UIColor redColor];
[self.navigationController.navigationBar addSubview:navBarLineView];

2
解决方案非常好用。以下是Swift代码:
let navBarLineView = UIView(frame: CGRectMake(0,
    CGRectGetHeight((navigationController?.navigationBar.frame)!),
    CGRectGetWidth((self.navigationController?.navigationBar.frame)!),
    1))

navBarLineView.backgroundColor = UIColor.whiteColor()

navigationController?.navigationBar.addSubview(navBarLineView)

这是一个使用自动布局在Swift中实现的子类 https://gist.github.com/soffes/0f87e42f1124d875cf754a44c9150704 - Sam Soffes

1
好的,如果您想要去除底部边框,您需要将阴影图像设置为空白图像。
[navigationBar setShadowImage:[UIImage new]];

所以,如果您想将其设置为另一种颜色,只需创建具有该颜色的图像即可。我使用下面的辅助函数从颜色创建图像(原始来源http://jslim.net/blog/2014/05/05/ios-customize-uitabbar-appearance/)。
+ (UIImage *)imageFromColor:(UIColor *)color forSize:(CGSize)size 
{
return [UIImage imageFromColor:color forSize:size withCornerRadius:0];
}

+ (UIImage *)imageFromColor:(UIColor *)color forSize:(CGSize)size     withCornerRadius:(CGFloat)radius
{
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);

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

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

// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContext(size);

// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius] addClip];
// Draw your image
[image drawInRect:rect];

// Get the image, here setting the UIImageView image
image = UIGraphicsGetImageFromCurrentImageContext();

// Lets forget about that we were drawing
UIGraphicsEndImageContext();

return image;
}

在我的导航栏中

[navigationBar setShadowImage:[UIImage imageFromColor:[UIColor redColor] forSize:CGSizeMake(CGRectGetWidth(self.tableView.frame), 1)]];

就是这样,它对我有效,希望这可以帮到你。请考虑更改已接受的答案,因为它不起作用并且可能会令人困惑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接