Setting an image for a UIButton in code
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Adding an image to a UIButton is straightforward in UIKit, but the details matter if you want the button to look right in different states and iOS versions. The core APIs are setImage(_:for:) for classic buttons and UIButton.Configuration for newer configuration-based buttons.
The Classic UIKit Approach
For a traditional button, you set the image for a specific control state:
setImage(_:for:) is state-based, so you can assign different images for .normal, .highlighted, .selected, and other button states.
Different Images for Different States
Buttons often need visual feedback when pressed or selected. You can provide separate images for each state:
Then toggle the state in your action:
This is usually better than swapping images manually inside every touch handler.
Asset Images Versus SF Symbols
If the image comes from your asset catalog, use UIImage(named:):
If the image is an SF Symbol, use UIImage(systemName:):
SF Symbols work especially well with UIButton(type: .system) because tinting and dynamic symbol rendering are built in.
Spacing Between Image and Title
A frequent problem is that the image sits too close to the title. In older button APIs, developers often adjusted edge insets. On newer iOS versions, UIButton.Configuration is cleaner.
For iOS 15 and later, this is usually the best way to build a polished image button.
Controlling Placement
If you want the image on the trailing side instead of the leading side, configuration-based buttons make it simple:
That is much more predictable than older inset juggling.
Tinted and Untinted Images
By default, system buttons may tint template-style images. If you want the original image colors preserved, change the rendering mode:
If the image should match your app color, keep it as a template image and set tintColor.
Auto Layout Example
Programmatic buttons are often laid out with constraints rather than frames:
The image setup stays the same regardless of whether you use frames or Auto Layout.
Common Pitfalls
The biggest pitfall is loading the wrong kind of image. UIImage(named:) looks in your app bundle and asset catalog, while UIImage(systemName:) is only for SF Symbols.
Another pitfall is wondering why the image color changed. That usually happens because the button is rendering the image as a template and applying tintColor.
A third pitfall is mixing old edge-inset tricks with modern UIButton.Configuration without a clear reason. On newer iOS versions, configuration-based layout is usually easier to maintain.
Finally, remember that the button image is state-specific. If the image disappears in a selected or disabled state, check which state you configured.
Summary
- Use
setImage(_:for:)to assign a button image in classic UIKit code - Use
UIButton.Configurationon newer iOS versions for cleaner image, title, and spacing control - Choose
UIImage(named:)for asset images andUIImage(systemName:)for SF Symbols - Configure images per state when the button should look different while selected or highlighted
- Pay attention to tinting, rendering mode, and spacing so the button looks intentional
Related reading
- Setting background colour of Android layout element
- Setting Corner Radius on UIImageView not working
- Setting custom UITableViewCells height
- Setting direction for UISwipeGestureRecognizer
- Setting text in EditText Kotlin
- Setting the zoom level for a MKMapView
- Setting UILabel text to bold
- Setting up buttons in SKScene
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack 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.