NSTextAttachment
UILabel
iOS Development
Swift Programming
Text Alignment

Center NSTextAttachment image next to single line UILabel

Master System Design with Codemia

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

Introduction

Placing an image next to text in a single-line UILabel is usually done with NSAttributedString and NSTextAttachment. The difficult part is vertical alignment: attachments are positioned relative to the text baseline, so icons often look too low or too high. A stable solution is to compute the baseline offset from font metrics and apply it through the attachment bounds or a companion attributed segment. This article shows a practical Swift implementation, explains why alignment drifts across fonts, and gives a reusable helper for predictable rendering in production UI.

Core Sections

Understand baseline and font metrics

Text rendering aligns glyphs using the baseline. Attachment images do not automatically center to cap height or x-height, so default placement can appear off.

Useful metrics from UIFont:

  • ascender
  • descender
  • capHeight
  • lineHeight

These values let you calculate a vertical offset that visually centers the icon near uppercase letter height.

Build an attributed string with controlled attachment bounds

A common approach is to resize the icon to match font cap height and then shift it slightly.

swift
1import UIKit
2
3func iconText(_ text: String,
4              image: UIImage,
5              font: UIFont,
6              textColor: UIColor) -> NSAttributedString {
7    let attachment = NSTextAttachment()
8    attachment.image = image
9
10    let targetHeight = font.capHeight
11    let scale = targetHeight / image.size.height
12    let targetWidth = image.size.width * scale
13
14    // Vertical tweak based on baseline and descender.
15    let yOffset = (font.capHeight - targetHeight) / 2 - 1
16    attachment.bounds = CGRect(x: 0, y: yOffset, width: targetWidth, height: targetHeight)
17
18    let result = NSMutableAttributedString(attachment: attachment)
19    result.append(NSAttributedString(string: " "))
20    result.append(NSAttributedString(
21        string: text,
22        attributes: [.font: font, .foregroundColor: textColor]
23    ))
24    return result
25}

Assign it as:

swift
label.attributedText = iconText("Verified", image: icon, font: .systemFont(ofSize: 15), textColor: .label)

Improve consistency across dynamic type

If users can change font size, recompute attachment size and offset each time the font changes. Avoid hardcoded pixel offsets independent of font metrics.

swift
1override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
2    super.traitCollectionDidChange(previousTraitCollection)
3    label.attributedText = iconText("Verified", image: icon, font: label.font, textColor: .label)
4}

For accessibility sizes, ensure the icon remains crisp by starting from a sufficiently high-resolution asset.

Alternative using baselineOffset

You can also use an attributed space with .baselineOffset around the attachment if needed for fine-grained alignment across fonts. In most cases, tuning attachment.bounds.y is simpler and easier to reason about.

Common Pitfalls

  • Using fixed attachment dimensions that do not scale with the label font, causing misalignment at different text sizes.
  • Ignoring baseline behavior and assuming images align like normal glyphs by default.
  • Hardcoding vertical offsets that work for one font but fail for custom fonts or dynamic type.
  • Forgetting to include a spacer between attachment and text, producing cramped visuals.
  • Reusing low-resolution icons and getting blurry rendering after scaling.

Production Readiness Check

Before closing the task, run a short validation loop on representative inputs and one intentional failure case. Confirm that your code path behaves correctly for normal data, empty data, and malformed data. Capture at least one measurable signal such as runtime, memory use, or error rate, then compare it to your baseline so regressions are visible. Keep this check lightweight so it can run in local development and CI without slowing feedback too much. A simple checklist plus one executable smoke test prevents most regressions after refactors and library upgrades.

text
11. Run happy-path example
22. Run edge-case example
33. Run failure-path example
44. Capture one performance or reliability metric
55. Verify output format and error handling

Summary

Centering an NSTextAttachment image next to single-line UILabel text is mostly about baseline-aware sizing and offset calculation. Use font metrics, set attachment bounds intentionally, and regenerate attributed strings when font size changes. Keep offsets data-driven rather than hardcoded for one device. With a small helper function and dynamic type handling, you can produce clean, consistent icon-text alignment across your iOS interface.


Course illustration
Course illustration

All Rights Reserved.