UIBarButtonItem
custom image
no border
iOS development
SwiftUI

UIBarButtonItem with custom image and no border

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Creating a UIBarButtonItem with a custom image and no visible border is a common iOS navigation requirement. Modern iOS already renders image-based bar button items without old-style bevel borders, but visual results depend on image rendering mode, tint color, and navigation bar appearance configuration. Developers often run into icons that look tinted incorrectly, misaligned touch targets, or inconsistent behavior between standard and scroll-edge appearances. The reliable approach is to configure both item and bar appearance intentionally and verify accessibility hit area.

Core Sections

Create an image bar button item

Use UIBarButtonItem(image:style:target:action:) for simple icon buttons.

swift
1let image = UIImage(systemName: "gearshape")
2let item = UIBarButtonItem(
3    image: image,
4    style: .plain,
5    target: self,
6    action: #selector(didTapSettings)
7)
8navigationItem.rightBarButtonItem = item

With .plain style and modern appearance defaults, no border is shown.

Control tint and rendering mode

If your asset has original colors, use .alwaysOriginal rendering. If you want consistent tinting, keep template rendering.

swift
1let icon = UIImage(named: "brand_icon")?.withRenderingMode(.alwaysOriginal)
2navigationItem.rightBarButtonItem = UIBarButtonItem(
3    image: icon,
4    style: .plain,
5    target: self,
6    action: #selector(didTapSettings)
7)

For template symbols:

swift
navigationController?.navigationBar.tintColor = .label

Configure navigation bar appearances consistently

Set both standard and scroll-edge appearance to avoid style jumps.

swift
1let appearance = UINavigationBarAppearance()
2appearance.configureWithOpaqueBackground()
3appearance.backgroundColor = .systemBackground
4appearance.buttonAppearance.normal.titleTextAttributes = [:]
5
6let navBar = navigationController?.navigationBar
7navBar?.standardAppearance = appearance
8navBar?.scrollEdgeAppearance = appearance

Use custom view for advanced layout

If you need custom spacing, animation, or badge overlays, create a UIButton and wrap it in UIBarButtonItem(customView:).

swift
1let button = UIButton(type: .system)
2button.setImage(UIImage(systemName: "bell"), for: .normal)
3button.addTarget(self, action: #selector(didTapBell), for: .touchUpInside)
4button.frame = CGRect(x: 0, y: 0, width: 32, height: 32)
5navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

Ensure minimum tap target remains usable.

Accessibility and testing

Set accessibility labels and run contrast checks, especially if icon tint changes across themes.

swift
navigationItem.rightBarButtonItem?.accessibilityLabel = "Settings"

Common Pitfalls

  • Expecting a border to disappear while using legacy appearance APIs that still add button decorations.
  • Using .alwaysOriginal images with low contrast against current navigation bar background.
  • Configuring only one navigation bar appearance state and getting inconsistent visuals while scrolling.
  • Creating tiny custom button frames that are hard to tap.
  • Forgetting accessibility labels for icon-only actions.

Verification Workflow

After implementing the main approach, run a short verification loop that proves behavior on realistic and adversarial inputs. Start with a small happy-path sample that should always pass, then add one edge case and one failure case that should be rejected or handled gracefully. Capture concrete outputs instead of relying on visual inspection alone. For operational code, record one measurable signal such as runtime, memory use, or error count so you can compare before and after future refactors.

Use this quick template during local development and CI:

text
11. Prepare deterministic sample input
22. Run expected-success scenario
33. Run expected-edge scenario
44. Run expected-failure scenario
55. Assert output schema and key values
66. Record one performance or reliability metric

This discipline catches most regressions caused by dependency upgrades, environment differences, or hidden assumptions in helper functions. It also makes handoffs easier because another engineer can reproduce behavior quickly without reverse-engineering your intent from source code alone.

Deployment Notes

Before rolling this pattern into production, add one small automated regression check tied to your most critical user path. Keep the check deterministic and fast, and run it on every dependency or configuration change. This extra guardrail catches subtle behavior drift that static review often misses, especially when environments differ between local machines and CI runners.

Summary

A borderless UIBarButtonItem with a custom image is straightforward when appearance and rendering are configured deliberately. Use plain-style image items for standard cases, and switch to custom views only when layout needs exceed default behavior. Keep tint, contrast, and hit targets consistent across navigation states. With these practices, icon bar buttons look clean and remain accessible.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.