iOS Development
UIButton Customization
Swift Programming
Interface Design
Mobile App UI

iPhone UIButton - image position

Master System Design with Codemia

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

Introduction

Positioning an image inside a UIButton is straightforward once you know which part of the content you are moving. The important distinction is that contentEdgeInsets affects the whole button content, while imageEdgeInsets and titleEdgeInsets adjust the image and title independently.

How UIButton lays out image and title

A classic UIButton can show an image and a title at the same time. By default, UIKit places the image on the leading side and the text after it. The final layout is influenced by three inset properties:

  • 'contentEdgeInsets adds padding around everything'
  • 'imageEdgeInsets shifts only the image'
  • 'titleEdgeInsets shifts only the title'

Here is a simple button configured in Swift:

swift
1let button = UIButton(type: .system)
2button.setTitle("Share", for: .normal)
3button.setImage(UIImage(systemName: "square.and.arrow.up"), for: .normal)
4button.tintColor = .systemBlue
5button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 12, bottom: 8, right: 12)

At this point, the image is still on the left. The insets only add breathing room.

Moving the image relative to the title

If you want extra spacing between the icon and text, use the image and title insets together:

swift
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -4, bottom: 0, right: 4)
button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: -4)

The numbers can feel unintuitive because you are offsetting two elements that UIKit already positions automatically. A practical rule is to make mirrored changes so the overall content stays visually centered.

For vertical layouts, the old inset approach becomes harder to maintain. In those cases, subclassing the button or using modern button configuration is often cleaner.

Putting the image on the right side

For right-aligned icons, many older examples manually swap insets. A better solution in modern iOS is to use semantic direction:

swift
button.semanticContentAttribute = .forceRightToLeft

With that setting, UIKit places the image after the title while preserving a natural layout model. This is usually simpler than calculating edge offsets by hand.

If you need precise spacing, combine semantic direction with content padding:

swift
button.semanticContentAttribute = .forceRightToLeft
button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 12, bottom: 8, right: 12)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 0, right: -6)

Modern approach with UIButton.Configuration

If your deployment target supports it, UIButton.Configuration is much easier than manual inset tuning.

swift
1var config = UIButton.Configuration.filled()
2config.title = "Continue"
3config.image = UIImage(systemName: "arrow.right.circle.fill")
4config.imagePlacement = .trailing
5config.imagePadding = 8
6config.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 16, bottom: 10, trailing: 16)
7
8let button = UIButton(configuration: config, primaryAction: nil)

This API is more expressive and handles many common layouts without the trial-and-error associated with imageEdgeInsets and titleEdgeInsets.

Debugging layout issues

If the image seems clipped or strangely offset, check these details:

  • the button may be too small for its content
  • large insets can push content outside the visible bounds
  • Auto Layout constraints may compress the button horizontally
  • the image itself may include transparent padding

A useful test is to temporarily set a background color and inspect the button frame:

swift
button.backgroundColor = UIColor.systemYellow.withAlphaComponent(0.2)
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.systemRed.cgColor

That makes it much easier to see whether the problem is the image position or the button's actual size.

When to subclass

If you need a layout such as icon above title, a dynamic badge, or asymmetric alignment that changes with state, subclassing UIButton can be justified. Overriding layout behavior is more work, but it is often cleaner than stacking several inset hacks on top of each other.

For standard left, right, and padded icon layouts, though, the built-in properties are usually enough.

Common Pitfalls

  • Using only imageEdgeInsets when the title also needs compensation to stay centered.
  • Forgetting that the image asset itself may already include empty padding.
  • Fighting Auto Layout when the real problem is an undersized button frame.
  • Manually reversing the image and title when semanticContentAttribute would be simpler.
  • Reaching for subclassing too early when UIButton.Configuration can handle the layout cleanly.

Summary

  • 'contentEdgeInsets affects the whole content area of the button.'
  • 'imageEdgeInsets and titleEdgeInsets move the icon and label independently.'
  • 'semanticContentAttribute is a clean way to place the image on the trailing side.'
  • 'UIButton.Configuration is the easiest modern API for image placement and spacing.'
  • Many apparent positioning bugs are really size, constraint, or asset-padding issues.

Course illustration
Course illustration

All Rights Reserved.