How to Hide the 1px Bottom Line of UINavigationBar

How to Hide the 1px Bottom Line of UINavigationBar

22 May 2024 Stephan Petzl Leave a comment Tech-Help

Sometimes, you may want your app’s navigation bar to blend seamlessly with the content, eliminating the 1px bottom line that can disrupt the visual flow. This guide will walk you through the best methods to achieve this, suitable for different iOS versions.

For iOS 13 and Later

iOS 13 introduced new properties that simplify hiding the navigation bar’s bottom line. You can use the .shadowColor property to remove the shadow.

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

For iOS 12 and Below

For older iOS versions, the process involves setting a custom shadow image. Note that it requires setting a custom background image as well.

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

If you prefer to avoid a background image, you can use solid color settings:

navigationBar.barTintColor = UIColor.red
navigationBar.isTranslucent = false
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.shadowImage = UIImage()

Maintaining Translucency

To keep the navigation bar translucent while hiding the bottom line, you can use a more intricate approach. This method involves finding and hiding the hairline UIImageView under the UINavigationBar.

private var shadowImageView: 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
}

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
}

Using Extensions

Another approach is to use extensions to hide the bottom hairline. Here’s a Swift extension that you can use:

import UIKit

extension UINavigationBar {
    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
    }
}

Conclusion

Depending on your iOS version and specific needs, you have multiple options to hide the 1px bottom line of the UINavigationBar. These methods ensure that your app’s navigation bar can seamlessly blend with the content, enhancing the visual appeal.

If you’re developing mobile applications and looking for ways to streamline your testing process, consider using Repeato. Repeato is a no-code test automation tool for iOS and Android that uses computer vision and AI to create, run, and maintain automated tests. This allows developers to focus on building great products while delegating test automation tasks to non-technical colleagues or QAs. For more information, check out our documentation.

Like this article? there’s more where that came from!