如何隐藏UINavigationBar 1px的底线

我有一个应用程序,有时需要其导航栏融入内容。

有谁知道如何摆脱或改变这个讨厌的小酒吧的颜色?

在下面的图像我有 – 我正在谈论这个1px高度线下面的“根视图控制器”

在这里输入图像描述

要做到这一点,你应该设置一个自定义的阴影图像。 但是要显示阴影图像,还需要设置一个自定义背景图像,引用Apple的文档:

要显示自定义阴影图像,还必须使用setBackgroundImage(_:for :)方法设置自定义背景图像。 如果使用默认的背景图像,那么无论此属性的值如何,都将使用默认的阴影图像。

所以:

let navigationBar = navigationController!.navigationBar navigationBar.setBackgroundImage(#imageLiteral(resourceName: "BarBackground"), for: .default) navigationBar.shadowImage = UIImage() 

以上是隐藏它的唯一“官方”方式。 不幸的是,它消除了酒吧的半透明性。

我不想要背景图片,只是颜色

你有这些选项:

  1. 纯色,不透明:

     navigationBar.barTintColor = UIColor.redColor() navigationBar.isTranslucent = false navigationBar.setBackgroundImage(UIImage(), for: .default) navigationBar.shadowImage = UIImage() 
  2. 创build填充颜色的小背景图像并使用它。

  3. 使用下面描述的“hacky”方法。 它也将保持半透明。

如何保持半透明?

要保持半透明性,你需要另一种方法,它看起来像一个黑客,但运作良好。 我们试图去除的阴影是在UINavigationBar下的一个发际线UIImageView 。 我们可以find它,并在需要时隐藏/显示。

下面的说明假定你只需要在UINavigationController层次结构的一个控制器中隐藏发际线。

  1. 声明实例variables:

     private var shadowImageView: UIImageView? 
  2. 添加find这个阴影的方法(细线) UIImageView:

     private func findShadowImage(under view: UIView) -> UIImageView? { if view is UIImageView && view.bounds.size.height <= 1 { return (view as! UIImageView) } for subview in view.subviews { if let imageView = findShadowImage(under: subview) { return imageView } } return nil } 
  3. 添加/编辑viewWillAppear/viewWillDisappear方法:

     override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if shadowImageView == nil { shadowImageView = findShadowImage(under: navigationController!.navigationBar) } shadowImageView?.isHidden = true } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) shadowImageView?.isHidden = false } 

同样的方法也应该适用于UISearchBar细线,以及(几乎)任何你需要隐藏的东西:)

非常感谢@Leo Natan最初的想法!

如果您只想使用实心的导航栏颜色,并将其设置在故事板中,请在AppDelegate类中使用以下代码通过外观代理删除1像素边框:

 [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]]; 

尝试这个:

 [[UINavigationBar appearance] setBackgroundImage: [UIImage new] forBarMetrics: UIBarMetricsDefault]; [UINavigationBar appearance].shadowImage = [UIImage new]; 

下面的图片有解释(iOS7 NavigationBar):

在这里输入图像描述

并检查这个问题: iOS7 – 更改UINavigationBar边框颜色

毕竟障碍,我已经find了这个解决scheme,删除导航栏的底部边界线。

迅速:

 self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow") 

目标C:

 [self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"]; 

想要添加Serhii的答案的Swift版本。 我使用以下方法创build了一个UIBarExtension.swift:

 import Foundation import UIKit extension UINavigationBar { func hideBottomHairline() { self.hairlineImageView?.isHidden = true } func showBottomHairline() { self.hairlineImageView?.isHidden = false } } extension UIToolbar { func hideBottomHairline() { self.hairlineImageView?.isHidden = true } func showBottomHairline() { self.hairlineImageView?.isHidden = false } } extension UIView { fileprivate var hairlineImageView: UIImageView? { return hairlineImageView(in: self) } fileprivate func hairlineImageView(in view: UIView) -> UIImageView? { if let imageView = view as? UIImageView, imageView.bounds.height <= 1.0 { return imageView } for subview in view.subviews { if let imageView = self.hairlineImageView(in: subview) { return imageView } } return nil } } 

迅速做到这一点:

 UINavigationBar.appearance().setBackgroundImage( UIImage(), forBarPosition: .Any, barMetrics: .Default) UINavigationBar.appearance().shadowImage = UIImage() 

在研究了Serhil的答案后,我创build了一个可以轻松隐藏发际线的UINavigationBar + Addition 。

 #import "UINavigationBar+Addition.h" - (void)viewDidLoad { [super viewDidLoad]; UINavigationBar *navigationBar = self.navigationController.navigationBar; [navigationBar hideBottomHairline]; } 

简单的解决scheme

  let navigationBar = self.navigationController?.navigationBar navigationBar?.setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default) navigationBar?.shadowImage = UIImage() 

为Swift 2.0更新了pxpgraphics的解决scheme

 extension UINavigationBar { func hideBottomHairline() { hairlineImageViewInNavigationBar(self)?.hidden = true } func showBottomHairline() { hairlineImageViewInNavigationBar(self)?.hidden = false } private func hairlineImageViewInNavigationBar(view: UIView) -> UIImageView? { if let imageView = view as? UIImageView where imageView.bounds.height <= 1 { return imageView } for subview: UIView in view.subviews { if let imageView = hairlineImageViewInNavigationBar(subview) { return imageView } } return nil } } extension UIToolbar { func hideHairline() { let navigationBarImageView = hairlineImageViewInToolbar(self)?.hidden = true } func showHairline() { let navigationBarImageView = hairlineImageViewInToolbar(self)?.hidden = false } private func hairlineImageViewInToolbar(view: UIView) -> UIImageView? { if let imageView = view as? UIImageView where imageView.bounds.height <= 1 { return imageView } for subview: UIView in view.subviews { if let imageView = hairlineImageViewInToolbar(subview) { return imageView } } return nil } } 

我使用UINavigationBar扩展,使我能够使用UIAppearance API来隐藏/显示阴影,或者使用Storyboard(或源代码)select哪个导航栏必须隐藏/显示阴影。 这里是扩展名:

 import UIKit private var flatAssociatedObjectKey: UInt8 = 0 /* An extension that adds a "flat" field to UINavigationBar. This flag, when enabled, removes the shadow under the navigation bar. */ @IBDesignable extension UINavigationBar { @IBInspectable var flat: Bool { get { guard let obj = objc_getAssociatedObject(self, &flatAssociatedObjectKey) as? NSNumber else { return false } return obj.boolValue; } set { if (newValue) { let void = UIImage() setBackgroundImage(void, forBarPosition: .Any, barMetrics: .Default) shadowImage = void } else { setBackgroundImage(nil, forBarPosition: .Any, barMetrics: .Default) shadowImage = nil } objc_setAssociatedObject(self, &flatAssociatedObjectKey, NSNumber(bool: newValue), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } } 

现在,要禁用所有导航栏上的阴影,您必须使用:

 UINavigationBar.appearance().flat = true 

或者你可以使用故事板来启用/禁用这种行为:

导航栏故事板

在Swift 3.0中

通过将以下代码添加到您的应用程序函数来编辑您的AppDelegate.swift:

 // Override point for customization after application launch. // Remove border in navigationBar UINavigationBar.appearance().shadowImage = UIImage() UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default) 

另一个select,如果你想保留半透明,你不想在你的应用程序中的每个UINavigationController的子类:

 #import <objc/runtime.h> @implementation UINavigationController (NoShadow) + (void)load { Method original = class_getInstanceMethod(self, @selector(viewWillAppear:)); Method swizzled = class_getInstanceMethod(self, @selector(swizzled_viewWillAppear:)); method_exchangeImplementations(original, swizzled); } + (UIImageView *)findHairlineImageViewUnder:(UIView *)view { if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) { return (UIImageView *)view; } for (UIView *subview in view.subviews) { UIImageView *imageView = [self findHairlineImageViewUnder:subview]; if (imageView) { return imageView; } } return nil; } - (void)swizzled_viewWillAppear:(BOOL)animated { UIImageView *shadow = [UINavigationController findHairlineImageViewUnder:self.navigationBar]; shadow.hidden = YES; [self swizzled_viewWillAppear:animated]; } @end 

Swift把这个

 UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default) UINavigationBar.appearance().shadowImage = UIImage() 

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
 Slightly Swift Solution func setGlobalAppearanceCharacteristics () { let navigationBarAppearace = UINavigationBar.appearance() navigationBarAppearace.tintColor = UIColor.white navigationBarAppearace.barTintColor = UIColor.blue navigationBarAppearace.setBackgroundImage(UIImage(), for: UIBarMetrics.default) navigationBarAppearace.shadowImage = UIImage() } 

在iOS8中,如果将UINavigationBar.barStyle设置为.Black,则可以将条的背景设置为无边框的纯色。

在Swift中:

 UINavigationBar.appearance().translucent = false UINavigationBar.appearance().barStyle = UIBarStyle.Black UINavigationBar.appearance().barTintColor = UIColor.redColor() 

这是一个非常简单的解决scheme:

 self.navigationController.navigationBar.clipsToBounds = YES; 

设置背景图像的问题是消除了模糊。 您可以在不设置背景图像的情况下将其删除。 在这里看到我的答案。

我知道这是一个古老的线索,但我find了一个很好的解决scheme:

子类UINavigationBar。 在您的UINavigationBar子类中,使用以下代码覆盖didAddSubview:

 - (void)didAddSubview:(UIView *)subview { [super didAddSubview:subview]; if ([subview isKindOfClass:[UIImageView class]]) { [subview setClipsToBounds:YES]; } } 

我只是为此创build了一个扩展…抱歉格式化(这是我的第一个答案)。

用法:

  override func viewDidLoad() { super.viewDidLoad() self.navigationController?.hideShadow = true } 

延期:

  UINavigationController.swift // Created by Ricardo López Rey on 16/7/15. import Foundation struct UINavigationControllerExtension { static var hideShadowKey : String = "HideShadow" static let backColor = UIColor(red: 247/255, green: 247/255, blue: 248/255, alpha: 1.0) } extension UINavigationController { var hideShadow : Bool { get { if let ret = objc_getAssociatedObject(self, &UINavigationControllerExtension.hideShadowKey) as? Bool { return ret } else { return false } } set { objc_setAssociatedObject(self,&UINavigationControllerExtension.hideShadowKey,newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) if newValue { self.navigationBar.setBackgroundImage(solidImage(UINavigationControllerExtension.backColor), forBarMetrics: UIBarMetrics.Default) self.navigationBar.shadowImage = solidImage(UIColor.clearColor()) } else { self.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default) } } } private func solidImage(color: UIColor, size: CGSize = CGSize(width: 1,height: 1)) -> UIImage { var rect = CGRectMake(0, 0, size.width, size.height) UIGraphicsBeginImageContextWithOptions(size, false, 0) color.setFill() UIRectFill(rect) var image: UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } } 

对于iOS 9用户,这对我有用。 只需添加这个:

 UINavigationBar.appearance().shadowImage = UIImage() 
 -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; UIImage *emptyImage = [UIImage new]; self.navigationController.navigationBar.shadowImage = emptyImage; [self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault]; } 

目标C对上述问题的回答

//删除导航栏的1px行

 [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault]; [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]]; [[UINavigationBar appearance] setTranslucent:NO]; [[UINavigationBar appearance] setTintColor:[UIColor yourColor]]; 

pxpgraphics的Swift 3.0的答案。

 import Foundation import UIKit extension UINavigationBar { func hideBottomHairline() { let navigationBarImageView = hairlineImageViewInNavigationBar(view: self) navigationBarImageView!.isHidden = true } func showBottomHairline() { let navigationBarImageView = hairlineImageViewInNavigationBar(view: self) navigationBarImageView!.isHidden = false } private func hairlineImageViewInNavigationBar(view: UIView) -> UIImageView? { if view is UIImageView && view.bounds.height <= 1.0 { return (view as! UIImageView) } let subviews = (view.subviews as [UIView]) for subview: UIView in subviews { if let imageView: UIImageView = hairlineImageViewInNavigationBar(view: subview) { return imageView } } return nil } } extension UIToolbar { func hideHairline() { let navigationBarImageView = hairlineImageViewInToolbar(view: self) navigationBarImageView!.isHidden = true } func showHairline() { let navigationBarImageView = hairlineImageViewInToolbar(view: self) navigationBarImageView!.isHidden = false } private func hairlineImageViewInToolbar(view: UIView) -> UIImageView? { if view is UIImageView && view.bounds.height <= 1.0 { return (view as! UIImageView) } let subviews = (view.subviews as [UIView]) for subview: UIView in subviews { if let imageView: UIImageView = hairlineImageViewInToolbar(view: subview) { return imageView } } return nil } } 

你应该添加一个视图到UISearchBar的底部

 let rect = searchController.searchBar.frame; let lineView : UIView = UIView.init(frame: CGRect.init(x: 0, y: rect.size.height-1, width: rect.size.width, height: 1)) lineView.backgroundColor = UIColor.init(hexString: "8CC73E") searchController.searchBar.addSubview(lineView) 
 [tabviewController.view setBackgroundColor:[UIColor blackColor]]; 

对我来说[UIColor blackColor]可能是你的背景颜色,如果你正在使用它, tabviewController是你的UITabBarController

这可能听起来很愚蠢,但是这个细线只有在viewController视图的背景颜色设置为任何颜色时才会出现,但是是白色的。 我很震惊地知道这个事实。

所以,如果你想让它消失没有太大的麻烦,只需将控制器的视图背景颜色设置为白色。

我的方法是:

 UINavigationBar.appearance().setBackgroundImage( UIImage(), forBarPosition: .Any, barMetrics: .Default) var _width:CGFloat! = self.navigationController?.navigationBar.layer.frame.width var _height:CGFloat! = self.navigationController?.navigationBar.layer.frame.height var navBarBg = UIView(frame:CGRectMake(0, 0, _width, _height)) //solid color for bg navBarBg.backgroundColor = UIColor.orangeColor() view.addSubview(navBarBg) 

这是另一种select – 我认为这只适用于不需要导航栏上的半透明(我没有)。 我刚刚添加了一个1像素高的UIView到导航栏的底部(导航栏下面的1像素)与我的导航栏相同的颜色:

 UIView *view = [[UIView alloc] init]; [view setBackgroundColor:self.navigationController.navigationBar.barTintColor]; [self.navigationController.navigationBar addSubview:view]; [view mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(@(1.0f)); make.leading.trailing.equalTo(self.navigationController.navigationBar); make.bottom.equalTo(self.navigationController.navigationBar).offset(1.0f); }]; 

我正在使用砌体添加约束。

酒吧风格的黑色为我做了。

 [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]; 

我有的所有属性(以防万一):

  [[UINavigationBar appearance] setBarTintColor:color]; [[UINavigationBar appearance] setTranslucent:NO]; [[UINavigationBar appearance] setShadowImage:[UIImage new]]; [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack]; 

AppDelegate中 ,这在全局上改变了NavBar的格式:

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default) UINavigationBar.appearance().shadowImage = UIImage() UINavigationBar.appearance().tintColor = UIColor.whiteColor() UINavigationBar.appearance().barTintColor = UIColor.redColor() UINavigationBar.appearance().translucent = false UINavigationBar.appearance().clipsToBounds = false UINavigationBar.appearance().backgroundColor = UIColor.redColor() UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : (UIFont(name: "FONT NAME", size: 18))!, NSForegroundColorAttributeName: UIColor.whiteColor()] } 

没有设法在特定的VC上实施任何不同的东西,但是这对90%的人有帮助