Remove border in navigationBar in swift

2019-01-29 19:57发布

问题:

i've been trying to remove the navigationBars border without luck. I've researched and people seem to tell to set shadowImage and BackgroundImage to nil, but this does not work in my case.

My code

    self.navigationController?.navigationBar.barTintColor = UIColor(rgba: "#4a5866")
    self.navigationController?.navigationBar.setBackgroundImage(UIImage(named: ""), forBarMetrics: UIBarMetrics.Default)
    self.navigationController?.navigationBar.shadowImage = UIImage(named: "")

illustration:

回答1:

The trouble is with these two lines:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(named: ""), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.shadowImage = UIImage(named: "")

Since you don't have an image with no name, UIImage(named: "") returns nil, which means the default behavior kicks in:

When non-nil, a custom shadow image to show instead of the default shadow image. For a custom shadow to be shown, a custom background image must also be set with -setBackgroundImage:forBarMetrics: (if the default background image is used, the default shadow image will be used).

You need a truly empty image, so just initialize with UIImage():

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()


回答2:

this will remove the shadow image altogether

for parent in self.navigationController!.navigationBar.subviews {
 for childView in parent.subviews {
     if(childView is UIImageView) {
         childView.removeFromSuperview()
     }
 }
}


回答3:

With Swift 2 you can do it this way:

AppDelegate file

Inside func application(..., didFinishLaunchingWithOptions launchOptions:...)

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

for Swift 3:

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


回答4:

Just write this in the extension of UINavigationBar

    extension UINavigationBar {

        func shouldRemoveShadow(_ value: Bool) -> Void {
            if value {
                self.setValue(true, forKey: "hidesShadow")
            } else {
                self.setValue(false, forKey: "hidesShadow")
            }
        }
    }

And in your viewController..

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        self.navigationController?.navigationBar.shouldRemoveShadow(true)        
    }

And to get this undone for any viewController, just pass the 'false'..



回答5:

Swift 4

Removing border:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for:.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.layoutIfNeeded()

Restoring border:

self.navigationController?.navigationBar.setBackgroundImage(nil, for:.default)
self.navigationController?.navigationBar.shadowImage = nil
self.navigationController?.navigationBar.layoutIfNeeded()


回答6:

Set barStyle to .Black before setting the tint:

self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.barStyle = .Black
self.navigationController?.navigationBar.barTintColor = UIColor.blueColor()


回答7:

Luca Davanzo's answer is great, but it does not work in iOS 10. I altered it to work in iOS 10 and below.

for parent in navigationController!.view.subviews {
    for child in parent.subviews {
        for view in child.subviews { 
            if view is UIImageView && view.frame.height == 0.5 {
                view.alpha = 0
            }
        }
    }
}

You can also extend UINavigationController and call this off of that. removeFromSuperview() on the line will not work on iOS 10, so I just set the alpha to 0 so this one call is compatible everywhere.



回答8:

To remove border from UINavigationBar in Swift 3+, use:

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


回答9:

for swift 3

in viewDidLoad method

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


回答10:

Updated for Swift 4 in case someone is wondering

navigationBar.shadowImage = UIImage()
navigationBar.backIndicatorImage = UIImage()

It's even less verbose now.



回答11:

This is the way if you want to do it without changing the background color:

// Remove the border ImageView from the NavigationBar background
func hideBottomBorder() {
    for view in navigationBar.subviews.filter({ NSStringFromClass($0.dynamicType) == "_UINavigationBarBackground" }) as [UIView] {
        if let imageView = view.subviews.filter({ $0 is UIImageView }).first as? UIImageView {
            imageView.removeFromSuperview()
        }
    }
}

NOTE: This might crash on a production app. Apparently the NavigationBar doesn't like its view disappearing



回答12:

Only this worked for me,

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

Ref



回答13:

for the swift3 you should write slightly different way:

 self.navigationController?.navigationBar.setBackgroundImage(UIImage(),
    for: UIBarMetrics.default)
   self.navigationController?.navigationBar.shadowImage = UIImage()


回答14:

The border line is an UIImageView and removing a subview which is an imageView will remove barButtonItems with UIImageView. Below code will help you remove it. Hope this helps someone who faced an issue like me.

for parent in self.navigationController!.navigationBar.subviews {
        for childView in parent.subviews {
            if childView.frame.height == 0.5 {
                childView.removeFromSuperview()
            }
        }
    }

The border UIImageView is only 0.5 in height so this code removes only that.



回答15:

Within AppDelegate, this has globally changed the format of the NavBar and removes the bottom line/border:

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

Haven't managed to implement anything different on a specific VC, but this will help 90% of people



回答16:

this is the answer in swift 3 base of Nate Cook answer

   self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationController?.navigationBar.shadowImage = UIImage()


回答17:

iOS 11 and Swift 4 You should try following if you want to remove the border but don't to make the navigitonbar translucent
self.navigationBar.shadowImage = UIImage()



回答18:

This is a streamlined version of Gaurav Chandarana's answer.

extension UINavigationBar {

    func hideShadow(_ value: Bool = true) {
        setValue(value, forKey: "hidesShadow")
    }
}