如何隐藏UINavigationBar 1px的底线
我有一个应用程序,有时需要其导航栏融入内容。
有谁知道如何摆脱或改变这个讨厌的小酒吧的颜色?
在下面的图像我有 – 我正在谈论这个1px高度线下面的“根视图控制器”
要做到这一点,你应该设置一个自定义的阴影图像。 但是要显示阴影图像,还需要设置一个自定义背景图像,引用Apple的文档:
要显示自定义阴影图像,还必须使用setBackgroundImage(_:for :)方法设置自定义背景图像。 如果使用默认的背景图像,那么无论此属性的值如何,都将使用默认的阴影图像。
所以:
let navigationBar = navigationController!.navigationBar navigationBar.setBackgroundImage(#imageLiteral(resourceName: "BarBackground"), for: .default) navigationBar.shadowImage = UIImage()
以上是隐藏它的唯一“官方”方式。 不幸的是,它消除了酒吧的半透明性。
我不想要背景图片,只是颜色
你有这些选项:
-
纯色,不透明:
navigationBar.barTintColor = UIColor.redColor() navigationBar.isTranslucent = false navigationBar.setBackgroundImage(UIImage(), for: .default) navigationBar.shadowImage = UIImage()
-
创build填充颜色的小背景图像并使用它。
-
使用下面描述的“hacky”方法。 它也将保持半透明。
如何保持半透明?
要保持半透明性,你需要另一种方法,它看起来像一个黑客,但运作良好。 我们试图去除的阴影是在UINavigationBar
下的一个发际线UIImageView
。 我们可以find它,并在需要时隐藏/显示。
下面的说明假定你只需要在UINavigationController
层次结构的一个控制器中隐藏发际线。
-
声明实例variables:
private var shadowImageView: UIImageView?
-
添加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 }
-
添加/编辑
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%的人有帮助