如何隐藏UINavigationBar 1px底线

Szy*_*zur 422 objective-c uinavigationbar ipad ios swift

我有一个应用程序,有时需要其导航栏与内容融为一体.

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

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

在此输入图像描述

Ser*_*nko 687

为此,您应该设置自定义阴影图像.但是要显示阴影图像,您还需要设置自定义背景图像,引用Apple的文档:

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

所以:

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

以上是隐藏它的唯一"官方"方式.不幸的是,它消除了酒吧的半透明度.

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

你有这些选择:

  1. 纯色,无透明度:

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

  3. 使用下面描述的'hacky'方法.它还会保持酒吧半透明.

如何保持酒吧半透明?

为了保持半透明,你需要另一种方法,它看起来像一个黑客,但运作良好.我们试图删除的阴影是在.shadowColor某处的发际线UIImageView.我们可以找到它并在需要时隐藏/显示它.

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

  1. 声明实例变量:

    private var shadowImageView: UIImageView?
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加找到这个阴影的方法(发际线) UINavigationController

    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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 添加/编辑UIImageView:方法:

    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
    }
    
    Run Code Online (Sandbox Code Playgroud)

相同的方法也适用于viewWillAppear/viewWillDisappear发际线,(几乎)你需要隐藏的任何其他东西:)

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

  • 您也可以设置`UINavigationBar`属性的视图:`clipsToBounds = YES` (96认同)
  • 只是要注意我有问题,我的iOS顶级状态栏变得半透明,我可以看到我的表视图滚动UINavigationBar后面.我通过设置setTranslucent = NO来修复此问题. (7认同)
  • @richarddas`pipsToBounds = YES`就像一个魅力!谢谢! (3认同)
  • clipsToBounds并不总是适用于某些布局.这个答案对我来说很完美.我只创建了一个UINavigationBar子类,并使用上面的代码隐藏-layoutSubview方法中的阴影图像.谢谢! (3认同)
  • 在iOS 10中,似乎当调用`viewWillAppear`时,我们无法获得`shadowImageView` (2认同)
  • `clipsToBounds = YES` 也会剪裁导航栏的上部,暴露状态栏的背景,如果你的 `navigationBar` 具有自定义颜色,这可能会出现问题。 (2认同)

Vis*_*han 218

以下可以帮助简单!

迅速:

self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
Run Code Online (Sandbox Code Playgroud)

目标C:

[self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"];
Run Code Online (Sandbox Code Playgroud)

  • 这是否在商店中被接受? (9认同)
  • 我正在使用Xcode 8和开发人员> iOS 8,除了这个之外,以上都没有. (6认同)
  • 也适用于Xcode 10 beta 5,iOS 12 (4认同)
  • 同样在XCode 8和> iOS 8上.这是唯一对我有用的答案. (2认同)
  • 适用于Xcode 9.3,iOS 11 (2认同)
  • 这并不健壮。Apple 可以随时停止使用“hidesShadow”keyPath,您的应用程序将因此崩溃 (2认同)

Ric*_*oor 144

如果您只想使用实心导航栏颜色并在故事板中进行设置,请在AppDelegate班级中使用此代码通过外观代理删除1像素边框:

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

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
Run Code Online (Sandbox Code Playgroud)

  • 这为您的代码库中的每个导航栏设置了全局...大多数时候不是您想要的. (2认同)

nul*_*ull 96

试试这个:

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

[UINavigationBar appearance].shadowImage = [UIImage new];
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

  • 在AppDelegate中执行此操作. (3认同)

pxp*_*ics 62

想要添加Swift版本的Serhii的答案.我创建了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
    }
}
Run Code Online (Sandbox Code Playgroud)


Osc*_*VGG 60

快速做到这一点:

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

UINavigationBar.appearance().shadowImage = UIImage()
Run Code Online (Sandbox Code Playgroud)

  • 它隐藏了UINavigationBar的整个背景:/ (3认同)
  • 注意:您必须将navigationBar的isTranslucent设置为false (3认同)
  • 在找到最简单的答案之前,很少将这一点放在列表中.+1! (2认同)

Jak*_*ůša 19

快速简单的解决方案

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

  • +1在所有答案中,这最终对我有用.它没有像其他答案一样搞乱状态栏,它解决了只更改一个导航控制器栏而不是项目中所有导航栏的问题. (3认同)

sam*_*ize 16

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

#import "UINavigationBar+Addition.h"

- (void)viewDidLoad {
    [super viewDidLoad];

    UINavigationBar *navigationBar = self.navigationController.navigationBar;
    [navigationBar hideBottomHairline];
}
Run Code Online (Sandbox Code Playgroud)


小智 14

在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)
Run Code Online (Sandbox Code Playgroud)


tf.*_*ves 11

针对Swift 2.0更新了pxpgraphics的解决方案

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
    }

}
Run Code Online (Sandbox Code Playgroud)


Far*_*med 11

Swift 4 //用于隐藏导航栏阴影线

navigationController?.navigationBar.shadowImage = UIImage()
Run Code Online (Sandbox Code Playgroud)


Gag*_*hir 11

也可以从情节提要中隐藏(在Xcode 10.1上使用)

通过添加运行时属性:hidesShadow-布尔值-True

在此处输入图片说明


glo*_*cha 11

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

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

    let appearance = UINavigationBarAppearance()
    appearance.shadowImage = nil
    appearance.shadowColor = nil
    navigationController.navigationBar.standardAppearance = appearance
Run Code Online (Sandbox Code Playgroud)


Alv*_*ivi 10

我使用UINavigationBar扩展,使我能够使用UIAppearance API隐藏/显示阴影,或选择使用Storyboard(或源代码)隐藏/显示阴影的导航栏.这是扩展名:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

UINavigationBar.appearance().flat = true
Run Code Online (Sandbox Code Playgroud)

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

导航栏故事板


Cha*_*lva 10

适用于 iOS 13+

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

let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = .green // Required background color
Run Code Online (Sandbox Code Playgroud)

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

self.navigationItem.standardAppearance = appearance
self.navigationItem.scrollEdgeAppearance = appearance
self.navigationItem.compactAppearance = appearance
Run Code Online (Sandbox Code Playgroud)


Sac*_*ane 9

Swift 4测试了 一线解决方案

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

override func viewDidLoad() {
    super.viewDidLoad()

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

}
Run Code Online (Sandbox Code Playgroud)


jhu*_*man 7

如果您想保留半透明度并且不想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
Run Code Online (Sandbox Code Playgroud)


UnR*_*ewa 6

斯威夫特把这个

UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
Run Code Online (Sandbox Code Playgroud)

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 5

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

}
Run Code Online (Sandbox Code Playgroud)


Mat*_*k90 5

Swift 4.2中的解决方案

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

只需将此函数放在第一个Viewcontroller上并调用 viewdidload


小智 5

对我有用的两行解决方案。尝试在 ViewDidLoad 方法中添加:

navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
Run Code Online (Sandbox Code Playgroud)