如何隐藏UINavigationBar 1px底线

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

有人知道怎么去掉或者改变这个烦人的小条的颜色吗?

在下图中,我说的是根视图控制器下面1px的高度线

enter image description here

222527 次浏览

试试这个:

[[UINavigationBar appearance] setBackgroundImage: [UIImage new]
forBarMetrics: UIBarMetricsDefault];


[UINavigationBar appearance].shadowImage = [UIImage new];

下图有解释(iOS7导航栏):

enter image description here

检查这个SO问题: iOS7 -改变UINavigationBar的边框颜色 < / p >

对于iOS 13:

使用.shadowColor属性

如果此属性为nil或包含透明颜色,则该栏不显示阴影

例如:

let navigationBar = navigationController?.navigationBar
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.shadowColor = .clear
navigationBar?.scrollEdgeAppearance = navigationBarAppearance

对于iOS 12及以下版本:

为此,您应该设置一个自定义阴影图像。但是为了显示阴影图像,你还需要设置一个自定义背景图像,引用自苹果的文档:

要显示自定义阴影图像,必须有自定义背景图像 也可以使用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. 创建小背景图像,充满颜色,并使用它。

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

如何保持酒吧的半透明?# #

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

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

  1. 声明实例变量:

    private var shadowImageView: UIImageView?
    
  2. 添加方法,查找此阴影(发际线)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]];

设置背景图像的问题是它消除了模糊。您可以在不设置背景图像的情况下删除它。见我的回答在这里

这可能听起来很愚蠢,但这个发际线只在viewController视图的背景色被设置为任何颜色时出现,除了白色。得知这个事实我很震惊。

所以如果你想让它消失,只要设置控制器的视图背景色为WHITE color。

在研究Serhil的答案后,我创建了一个豆荚UINavigationBar +添加,可以很容易地隐藏发际线。

#import "UINavigationBar+Addition.h"


- (void)viewDidLoad {
[super viewDidLoad];


UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar hideBottomHairline];
}

我知道这是一个老话题,但我找到了一个非常有效的解决方案:

UINavigationBar < p >子类。 在你的UINavigationBar子类中,用下面的代码重写didAddSubview
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];


if ([subview isKindOfClass:[UIImageView class]]) {
[subview setClipsToBounds:YES];
}
}

想把Serhii回答的Swift版本加进去。我用以下代码创建了一个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
}
}

如果你想要保持半透明,并且你不想在你的应用程序中子类化每个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
[tabviewController.view setBackgroundColor:[UIColor blackColor]];

为我做的[UIColor blackColor]可能是你的背景色, tabviewController是你的UITabBarController,如果你正在使用它!< / p >

这里有一个非常简单的解决方案:

self.navigationController.navigationBar.clipsToBounds = YES;
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()


}

快速做这件事的方法:

UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()

我的方法:

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)

pxpgraphics”解决方案为Swift 2.0更新

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
}


}

我刚刚为这个创建了一个扩展…关于格式的问题很抱歉(这是我的第一个答案)。

用法:

  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
}




}

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

迅速:

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

我使用UINavigationBar扩展,使我能够隐藏/显示使用UIAppearance API的阴影或选择哪个导航栏必须隐藏/显示使用故事板(或源代码)的阴影。这是扩展:

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

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

Navigation Bar Storyboard

这里有另一个选择-我认为这只适用于你不需要半透明的导航栏(我没有)。我只是在导航栏的底部添加了一个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);
}];

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

简单的解决方案

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

酒吧风格的黑色适合我。

[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

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

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

斯威夫特说

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

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];


UIImage *emptyImage = [UIImage new];
self.navigationController.navigationBar.shadowImage = emptyImage;
[self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault];
}

AppDelegate中,这已经全局地改变了导航栏的格式:

 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%的人

对我来说,最简单的方法是创建一个具有所需颜色的png(它只需要一个像素乘以一个像素的尺寸),然后设置backgroundImage和shadowImage:

let greenPixel = UIImage(named: "TheNameOfYourPng")
navigationBar.setBackgroundImage(greenPixel, forBarMetrics: UIBarMetrics.Default)
navigationBar.shadowImage = greenPixel

在子视图中找到发际线的一个很好的简短Swift函数是:

 func findHairLineInImageViewUnder(view view: UIView) -> UIImageView? {
if let hairLineView = view as? UIImageView where hairLineView.bounds.size.height <= 1.0 {
return hairLineView
}


if let hairLineView = view.subviews.flatMap({self.findHairLineInImageViewUnder(view: $0)}).first {
return hairLineView
}


return nil
}

对于iOS 9用户,这对我来说很有效。只要加上这个:

UINavigationBar.appearance().shadowImage = UIImage()

下面是破解方法。因为它在关键路径上工作,将来可能会崩溃。但就目前而言,它的运作符合预期。

迅速:

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

Objective - C:

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

以上问题的答案

//删除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)

在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)

斯威夫特3中,我们这样做

对于任何视图控制器:

navigationBar.shadowImage = UIImage()
setBackgroundImage(UIImage(), for: .default)

对于整个应用程序:

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

我也遇到了同样的问题,但没有一个答案真正令人满意。以下是我对Swift3的看法:

func hideNavigationBarLine() {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
}

简单地从viewDidLoad ()中调用它。

Xamarin的形式中,这对我有用。只需在AppDelegate.cs上添加这个:

UINavigationBar.Appearance.ShadowImage = new UIImage();

< >强劲迅速4 //隐藏导航栏阴影线

. //
navigationController?.navigationBar.shadowImage = UIImage()

嗨,这适用于Swift 4。

    override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.isTranslucent = false
}

你需要把这个放在viewDidLayoutSubviews而不是viewDidLoad

这里有一个不使用任何图像的方法,这是唯一适合我的方法:

self.navigationController.navigationBar.layer.shadowOpacity = 0;

不幸的是,您需要在每个不希望出现该行的文件上执行此操作。在appDelegate中没有办法这样做。

编辑:

不需要将shadowColor设置为nil,这是你唯一需要的行。

Swift 4测试 一行解

Viewdidload() < p > 设置导航控制器的用户默认值为true的键" hidesshado "

override func viewDidLoad() {
super.viewDidLoad()


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


}

也可以从故事板中隐藏(适用于Xcode 10.1)

通过添加运行时属性:hidshadow - Boolean - True

enter image description here

斯威夫特4.2:中的解决方案

private func removeHairlineFromNavbar() {
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
for: .any,
barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}

只需要把这个函数放在第一个视图控制器中,并在viewdidload中调用它

从iOS 13开始,就有一个系统API来设置或删除阴影

UIKit使用shadowImage和shadowColor属性来确定阴影的 外观。当shadowImage为nil时,该工具条显示默认的着色阴影 根据shadowColor属性中的值。如果shadowColor为nil或

.

.

.
    let appearance = UINavigationBarAppearance()
appearance.shadowImage = nil
appearance.shadowColor = nil
navigationController.navigationBar.standardAppearance = appearance

https://developer.apple.com/documentation/uikit/uibarappearance/3198009-shadowimage

简单的解决方案- Swift 5

  1. 创建一个扩展名:

    extension UIImage {
    
    
    class func hideNavBarLine(color: UIColor) -> UIImage? {
    
    
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    let context = UIGraphicsGetCurrentContext()
    context?.setFillColor(color.cgColor)
    context?.fill(rect)
    
    
    
    
    let navBarLine = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return navBarLine
    }
    }
    
  2. Add this to viewDidLoad():

    self.navigationController?.navigationBar.shadowImage = UIImage.hideNavBarLine(color: UIColor.clear)
    

两条线的解决方案对我来说很有效。尝试在ViewDidLoad方法中添加这个:

navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
        if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor          = Colors.color_app
appearance.titleTextAttributes      = [.foregroundColor : UIColor.white]
appearance.largeTitleTextAttributes = [.foregroundColor : UIColor.white]
appearance.shadowColor = .clear
appearance.shadowImage = UIImage()
            

UINavigationBar.appearance().tintColor            = .white
UINavigationBar.appearance().standardAppearance   = appearance
UINavigationBar.appearance().compactAppearance    = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
} else {
UINavigationBar.appearance().barTintColor        = Colors.color_app
UINavigationBar.appearance().tintColor           = .white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
if #available(iOS 11.0, *) {
UINavigationBar.appearance().largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
}
UINavigationBar.appearance().isTranslucent = false
            

UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
}

编写自己的初始化式:D

import Foundation
import UIKit


extension UINavigationController {
convenience init(rootViewController : UIViewController, hidesShadow : Bool) {
self.init(rootViewController : rootViewController)
self.navigationBar.setValue(hidesShadow, forKey: "hidesShadow")
if hidesShadow {
self.extendedLayoutIncludesOpaqueBars = true
self.navigationBar.isTranslucent = false
}
}
}

不要使用navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")是非常重要的,因为在任何时候,Apple都可以删除“hidesShadow"关键路径。如果他们这样做,任何使用这个调用的应用程序都会崩溃。因为你没有访问类的直接API,所以这个调用会被App Store拒绝。

从iOS 13开始,为了确保效率,你可以做以下事情:

navigationBar.standardAppearance.shadowColor = nil

这里有一个非常重要的注意事项——改变UIViewControllernavigationItem的外观要比直接改变navigationBar的外观灵活得多。

为什么这么问?

原因很简单,navigationItem绑定到单个UIViewController,并表示该特定UIViewControllernavigationBar的状态。这是很大的,因为你不必在viewWillAppear(或类似的东西)中处理不同视图控制器之间的导航栏更改,就像你在改变navigationBar;记住,它是在给定导航堆栈(UINavigationController)的所有视图控制器之间共享的,在一个地方更改它会对堆栈上的所有视图控制器更改。

你只要为一个特定的视图控制器设置正确的UINavigationBarAppearance, UIKit就会正确地更新导航栏样式,这取决于当前哪个视图控制器是导航堆栈上的顶视图控制器。

navigationItem.standardAppearance` = `UINavigationBarAppearance()

适用于iOS 13+

诀窍是用TransparentBackground初始化'UINavigationBarAppearance'。然后,您可以轻松地删除导航栏的水平线。

let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = .green // Required background color

最后,按照apple的建议将外观更改添加到导航项中。

self.navigationItem.standardAppearance = appearance
self.navigationItem.scrollEdgeAppearance = appearance
self.navigationItem.compactAppearance = appearance