navigationBar
border removal
iOS development
UI customization
app design

How to remove border of the navigationBar?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The thin line under a UINavigationBar is often called the hairline. It can clash with custom designs, especially when you want a flat or transparent header. Removing it reliably depends on iOS version and whether your app uses modern appearance APIs.

Understand Where the Border Comes From

On recent iOS versions, the line is usually the shadow rendered by navigation bar appearance settings. On older versions, it may come from a default shadow image. The right fix is to configure the bar appearance intentionally, not to hide random subviews.

If your app targets iOS 13 or later, use UINavigationBarAppearance. It gives one consistent place to define background color, shadow color, and text attributes. This is the most stable approach across device types and orientation changes.

Remove the Border with UINavigationBarAppearance

Set shadowColor to clear or nil, then apply the same appearance to all relevant states. Many teams forget scrollEdgeAppearance, which can make the line reappear when a scroll view reaches the top.

swift
1import UIKit
2
3@main
4class AppDelegate: UIResponder, UIApplicationDelegate {
5    var window: UIWindow?
6
7    func application(
8        _ application: UIApplication,
9        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
10    ) -> Bool {
11        let appearance = UINavigationBarAppearance()
12        appearance.configureWithOpaqueBackground()
13        appearance.backgroundColor = .systemBackground
14        appearance.shadowColor = .clear
15
16        let navBar = UINavigationBar.appearance()
17        navBar.standardAppearance = appearance
18        navBar.scrollEdgeAppearance = appearance
19        navBar.compactAppearance = appearance
20
21        return true
22    }
23}

If you want a transparent bar, start with configureWithTransparentBackground and still set shadowColor to clear. That avoids the faint line that can remain on some combinations of defaults.

Legacy Support for Older iOS Versions

For older targets, remove the line by setting an empty shadow image and background image. This is less flexible than the modern API, but still useful for legacy maintenance.

swift
1import UIKit
2
3final class LegacyStyleController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        if let navBar = navigationController?.navigationBar {
8            navBar.setBackgroundImage(UIImage(), for: .default)
9            navBar.shadowImage = UIImage()
10            navBar.isTranslucent = false
11            navBar.barTintColor = .white
12        }
13    }
14}

Keep styling centralized when possible. Applying these changes in every screen controller can create subtle inconsistencies over time.

SwiftUI Integration Notes

Even in SwiftUI apps, navigation styling often flows through UIKit appearance APIs. If you notice different behavior between screens, check whether some routes are embedded in a separate navigation stack. Mixed navigation architecture can cause one stack to use default appearance while another uses custom settings.

Testing on both large title and inline title states is important. The bar may switch appearance classes while scrolling, and any missing state configuration can bring back the border unexpectedly.

If your design supports theme changes, verify behavior during light and dark mode transitions. Some teams set a clear shadow color but forget to set background color consistently, which causes contrast artifacts that look like a border on only one theme. Snapshot tests for both appearances help catch this early.

Common Pitfalls

A frequent mistake is setting only standardAppearance and forgetting scrollEdgeAppearance. The header looks correct at first, then the line appears while scrolling.

Another issue is setting global appearance and then overriding one screen locally with partial configuration. This can lead to inconsistent text color, background style, or border state across pushes and pops.

Developers also rely on private subview traversal to hide the hairline. That approach is fragile and may break in iOS updates. Prefer documented appearance properties.

Finally, when using translucent or transparent bars, content inset behavior can create visual artifacts that look like borders. Verify safe area and scroll inset settings before assuming the shadow line is still active.

Summary

  • On iOS 13 and later, use UINavigationBarAppearance as the primary solution.
  • Set shadowColor and all appearance states to keep behavior consistent.
  • For older iOS versions, use empty background and shadow images.
  • Avoid private view hacks for long term stability.
  • Test large title, inline title, and scroll edge transitions on real devices.

Course illustration
Course illustration

All Rights Reserved.