15

Can anyone advise me on how the border below the navigation bar can be changed?

enter image description here

I would like to change it from the current black light to a softer color. Appreciate any help here

Man of One Way
  • 3,904
  • 1
  • 26
  • 41
Zhen
  • 12,361
  • 38
  • 122
  • 199

6 Answers6

43

I do not think there is a method to change the border color of the navigation color, other than the tintColor property of the UINavigationBar.

I would suggest that you create a UIView of that border size and place it below the navigation bar / add it as a subView.

UIView *navBorder = [[UIView alloc] initWithFrame:CGRectMake(0,navigationBar.frame.size.height-1,navigationBar.frame.size.width, 1)]; 

// Change the frame size to suit yours //

[navBorder setBackgroundColor:[UIColor colorWithWhite:200.0f/255.f alpha:0.8f]];
[navBorder setOpaque:YES];
[navigationBar addSubview:navBorder];
[navBorder release];
Legolas
  • 12,145
  • 12
  • 79
  • 132
9

In Swift like the @Legolas answer:

if let navigationController = self.navigationController {

   let navigationBar = navigationController.navigationBar     
   let navBorder: UIView = UIView(frame: CGRectMake(0, navigationBar.frame.size.height - 1, navigationBar.frame.size.width, 1))
   // Set the color you want here
   navBorder.backgroundColor = UIColor(red: 0.19, green: 0.19, blue: 0.2, alpha: 1)
   navBorder.opaque = true
   self.navigationController?.navigationBar.addSubview(navBorder)
}

You can put in the viewDidLoad() of your UIViewController.

Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
Victor Sigler
  • 23,243
  • 14
  • 88
  • 105
  • 2
    The `y` of the view frame origin should be `navigationBar.frame.size.height` instead of `navigationBar.frame.size.height - 1` mentioned above. – Zhao Mar 22 '16 at 07:28
4

For iOS 7 you could use this:

[self.navigationController.navigationBar setShadowImage:[UIImage new]];
ChrisF
  • 134,786
  • 31
  • 255
  • 325
2

You can also add a child view to your nav bar

The following code will add a 4 pixel deep blue border below your navigation bar

UINavigationBar* navBar = self.navigationController.navigationBar;
    int borderSize = 4;
    UIView *navBorder = [[UIView alloc] initWithFrame:CGRectMake(0,navBar.frame.size.height-borderSize,navBar.frame.size.width, borderSize)];
    [navBorder setBackgroundColor:[UIColor blueColor]];
    [self.navigationController.navigationBar addSubview:navBorder];
gheese
  • 1,170
  • 1
  • 11
  • 17
1

I found a couple of issues with the previous answers:

  • if you add a subview: Upon rotation of the device, the border will not have the correct frame anymore
  • if you set the shadowImage to nil, then you cannot customize the shadow of the navigationBar.

One way of solving this would be to use autolayout:

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
  }
}

The reason why I return the border is that during rotation you do see it in the middle of the navigation bar, so I hide it during the rotation.

Pierre
  • 1,053
  • 7
  • 17
-1

Despite navigationBar is read-only property for UINavigationController you can avoid this restriction by "setValue:forKey:". This method was approved on 5 applications successfully submitted to AppStore.

You can subclass UINavigationBar and change drawRect: method as you want. For example,

@implementation CustomNavigationBar

- (void) drawRect:(CGRect)rect
{
    [super drawRect:rect];
    UIImage *backgroundImage = ImageFromColor(WANTED_COLOR);
    [backgroundImage drawInRect:rect];
}

After you can subclass UINavigationController and change initWithRootViewController:

- (id) initWithRootViewController:(UIViewController *)rootViewController
{
    self = [super initWithRootViewController:rootViewController]; 
    if (self) 
    {
        CustomNavigationBar *navBar = [CustomNavigationBar new];
        [self setValue:navBar forKey:@"navigationBar"];
    }
    return self;
}

Also you can vary this approach by making Category for UINavigationController and implementing method swizzling for initWithRootViewController:

P.S. Yesterday my new app appeared at AppStore without any problem with this approach.

malex
  • 9,874
  • 3
  • 56
  • 77