Implementing alternate icons in iOS
Overview of what you need to do to allow users to select custom icons. With common pitfalls and iPad implementation.
Published: July 8, 2021 Sponsored See booksSo far I have implemented alternate icons in a few apps and since I have met quite a few pitfalls along the way, decided to write up this guide. It will show you exactly what you need to do to have alternative icons and extra steps needed for iPad. Let's go.
Before we start, let's briefly look at what are the individual steps.
- Prepare icons and add them to project
- Modify Info.plist to list these icons
- Implement icon switching in code
Preparing icons
Obviously, if you want to offer alternate / alternative / dynamic icons, you need to first create some 😃 These can be either variants with different backgrounds or entirely different icons.
For iPhone apps you need you need 120x120 and 180x180 pixel files. Preferably PNG.
These files need to be added to group in your project - not in Assets catalog!
Let's use the name "switchBuddyBlueIcon" as an example. We will need this later for Info.plist
and code.
For the 120x120 and 180x180 dimensions we would add these files:
- switchBuddyBlueIcon@2x.png
- switchBuddyBlueIcon@3x.png
If your app also runs on iPad, you need two additional sizes. This isn't strictly true, but you will be getting App Store Connect emails about "Missing recommended icon".
To avoid this, prepare 152x152 and 167x167 files with names as follow:
- switchBuddyBlueIcon@2x~ipad.png
- switchBuddyBlueIcon@3x~ipad.png
Note the "~ipad" in the names.
Modifying Info.plist
The next required step is entry in Info.plist
which lists all you alternative icon names.
It looks like this:
(I would recommend opening the file as "Source Code")
<key>CFBundleIcons</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>switchBuddyBlueIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>switchBuddyBlueIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
We first have key CFBundleIcons
which has CFBundleAlternateIcons
key to list all the available alternative icons and also entry for the primary one.
I am using the icon name both for key and value without the extension. So just "switchBuddyBlueIcon". For more icons, you would create new dict
entry in the CFBundleAlternateIcons
.
To be clear, I am talking about this fragment:
<key>switchBuddyBlueIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>switchBuddyBlueIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
Copy it below the original and change the icon name.
Modifying Info.plist for iPad
Once again, iPad requires extra steps, without these your icons won't change on iPad.
You basically need to copy the CFBundleIcons
block and append ~ipad
like this:
<key>CFBundleIcons~ipad</key>
<dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>switchBuddyBlueIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>switchBuddyBlueIcon</string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
</dict>
Done!
Changing the icon in code
The methods and properties to work with alternative icons are available on the UIApplication.share
property.
To start, you can check if alternative icons are supported:
UIApplication.shared.supportsAlternateIcons
The docs are super brief:
The value of this property is true only when the system allows you to change the icon of your app.
But it doesn't say under which conditions this would be false
. Anyway, if you want to be safe, you can check this property before showing user the option to pick alternate icons.
Let's change the icon!
UIApplication.shared.setAlternateIconName("switchBuddyBlueIcon", completionHandler: nil)
And done! System will show the prompt confirming icon change. You can optionally check for errors with the completionHandler
but if you did the previous steps correctly, there should be no need.
Setting the icon back to default
Want to reset alternative icon and use the default one? Pass nil
as the icon name:
UIApplication.shared.setAlternateIconName(nil, completionHandler: nil)
Indicating which icon is currently selected
As a small UX improvement, I am showing selection indicator for currently active icon in my apps. Some also have app icon in about page footer, where I also display alternative icons if needed.
You can achieve this by checking this property:
UIApplication.shared.alternateIconName
nil
means default icon is selected, otherwise it will contain name of the alternate icon.
And that should be everything there is to alternate icons!
Uses: Xcode 12 & Swift 5.3