UIButton
imageSize
iOS development
Swift
user interface customization

How to adjust an UIButton's imageSize?

Master System Design with Codemia

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

Introduction

UIButton does not have a single imageSize property that resizes any image for you. The right approach depends on what kind of image you are using. For SF Symbols, use symbol configuration. For bitmap assets, resize the image itself or control the imageView layout carefully. Insets change positioning and padding, but they do not truly change the underlying image size.

Start by Distinguishing Symbol Images from Bitmap Images

This distinction matters because UIKit treats the two cases differently.

  • SF Symbols are vector-based and are meant to scale through symbol configuration.
  • bitmap images such as PNG assets have a fixed pixel size and usually need resizing before assignment.

If you apply the wrong technique, the button may appear unchanged, blurry, or incorrectly aligned.

SF Symbols: Use Symbol Configuration

For SF Symbols, this is the cleanest approach:

swift
1import UIKit
2
3let button = UIButton(type: .system)
4let image = UIImage(systemName: "star.fill")
5let config = UIImage.SymbolConfiguration(pointSize: 24, weight: .medium)
6button.setImage(image?.applyingSymbolConfiguration(config), for: .normal)

This resizes the symbol while preserving its vector quality.

On modern iOS, UIButton.Configuration also works well:

swift
1import UIKit
2
3var config = UIButton.Configuration.plain()
4config.image = UIImage(systemName: "paperplane.fill")
5config.preferredSymbolConfigurationForImage = UIImage.SymbolConfiguration(pointSize: 22)
6
7let button = UIButton(configuration: config)

If your image is an SF Symbol, this is usually the best solution.

Bitmap Images: Resize the UIImage

For ordinary PNG or JPEG assets, there is no equivalent vector scaling behavior. A practical solution is to render a resized image before setting it on the button.

swift
1import UIKit
2
3func resizedImage(_ image: UIImage, to size: CGSize) -> UIImage {
4    let renderer = UIGraphicsImageRenderer(size: size)
5    return renderer.image { _ in
6        image.draw(in: CGRect(origin: .zero, size: size))
7    }
8}
9
10let original = UIImage(named: "avatar")!
11let scaled = resizedImage(original, to: CGSize(width: 20, height: 20))
12
13let button = UIButton(type: .system)
14button.setImage(scaled, for: .normal)

This is reliable because the button receives an image that already has the intended rendered size.

If the same resized image is used repeatedly, cache it instead of recreating it every layout pass.

Control Layout with Content Modes and Insets

After the image size is correct, adjust the button layout.

swift
button.imageView?.contentMode = .scaleAspectFit
button.contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)

This affects how the image sits inside the button, but it is not a resizing API by itself.

imageEdgeInsets and contentEdgeInsets are mostly about spacing. They can make the visible image area smaller or larger by changing padding, but they do not replace proper image sizing.

Be Careful with imageView?.frame

A common beginner move is trying to set button.imageView?.frame.size directly. That is fragile because UIButton manages its internal subviews during layout. Your manual frame changes may be overwritten.

If you absolutely must customize layout beyond the standard APIs, you are often better off with one of these designs:

  • subclass the button and override layout behavior carefully
  • place an UIImageView and UILabel inside a custom container view
  • use UIButton.Configuration for modern layout control where possible

The less you fight UIButton’s layout engine, the better.

Pick a Strategy That Matches the Asset Type

A practical rule set is:

  • SF Symbol: use symbol configuration
  • bitmap asset: resize the image itself
  • spacing or placement problem: use insets or button configuration
  • very custom layout: build a custom control instead of over-tuning UIButton

This keeps the code understandable and avoids hacks that break after the next layout pass.

Common Pitfalls

The biggest pitfall is trying to use padding APIs such as imageEdgeInsets as if they were true image-resizing APIs.

Another issue is resizing a bitmap asset repeatedly during scrolling or layout, which can waste CPU time. Resize once and reuse the result.

Developers also often try to mutate imageView?.frame directly and then wonder why UIKit resets it.

Finally, do not use bitmap resizing logic for SF Symbols when symbol configuration already provides a sharper and simpler result.

Summary

  • 'UIButton has no universal imageSize property.'
  • For SF Symbols, use UIImage.SymbolConfiguration or preferredSymbolConfigurationForImage.
  • For bitmap assets, resize the UIImage before assigning it to the button.
  • Insets help with spacing and placement, not true image resizing.
  • If layout becomes too custom, a dedicated custom view is often cleaner than forcing UIButton to do everything.

Course illustration
Course illustration

All Rights Reserved.